--- linux-xilinx-6.8.0.orig/.editorconfig +++ linux-xilinx-6.8.0/.editorconfig @@ -5,7 +5,6 @@ [{*.{awk,c,dts,dtsi,dtso,h,mk,s,S},Kconfig,Makefile,Makefile.*}] charset = utf-8 end_of_line = lf -trim_trailing_whitespace = true insert_final_newline = true indent_style = tab indent_size = 8 @@ -13,7 +12,6 @@ [*.{json,py,rs}] charset = utf-8 end_of_line = lf -trim_trailing_whitespace = true insert_final_newline = true indent_style = space indent_size = 4 @@ -26,7 +24,6 @@ [*.yaml] charset = utf-8 end_of_line = lf -trim_trailing_whitespace = unset insert_final_newline = true indent_style = space indent_size = 2 --- linux-xilinx-6.8.0.orig/.github/pull_request_template.md +++ linux-xilinx-6.8.0/.github/pull_request_template.md @@ -0,0 +1,3 @@ +Please do not submit a Pull Request via github. Our project makes use of +mailing lists for patch submission and review. For more details please see +https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842172/Create+and+Submit+a+Patch --- linux-xilinx-6.8.0.orig/Documentation/ABI/stable/sysfs-block +++ linux-xilinx-6.8.0/Documentation/ABI/stable/sysfs-block @@ -101,6 +101,16 @@ devices that support receiving integrity metadata. +What: /sys/block//partscan +Date: May 2024 +Contact: Christoph Hellwig +Description: + The /sys/block//partscan files reports if partition + scanning is enabled for the disk. It returns "1" if partition + scanning is enabled, or "0" if not. The value type is a 32-bit + unsigned integer, but only "0" and "1" are valid values. + + What: /sys/block///alignment_offset Date: April 2009 Contact: Martin K. Petersen --- linux-xilinx-6.8.0.orig/Documentation/ABI/stable/sysfs-driver-firmware-zynqmp +++ linux-xilinx-6.8.0/Documentation/ABI/stable/sysfs-driver-firmware-zynqmp @@ -254,3 +254,16 @@ The expected result is 500. Users: Xilinx + +What: /sys/devices/platform/firmware\:zynqmp-firmware/last_reset_reason +Date: Nov 2023 +KernelVersion: 6.7 +Contact: "Ronak Jain" +Description: + This sysfs interface allows to get last reset reason. + + Usage: + Get last reset reason + # cat /sys/devices/platform/firmware\:zynqmp-firmware/last_reset_reason + +Users: Xilinx --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/debugfs-driver-qat +++ linux-xilinx-6.8.0/Documentation/ABI/testing/debugfs-driver-qat @@ -81,3 +81,29 @@ : Number of Compress and Verify (CnV) errors and type of the last CnV error detected by Acceleration Engine N. + +What: /sys/kernel/debug/qat__/heartbeat/inject_error +Date: March 2024 +KernelVersion: 6.8 +Contact: qat-linux@intel.com +Description: (WO) Write to inject an error that simulates an heartbeat + failure. This is to be used for testing purposes. + + After writing this file, the driver stops arbitration on a + random engine and disables the fetching of heartbeat counters. + If a workload is running on the device, a job submitted to the + accelerator might not get a response and a read of the + `heartbeat/status` attribute might report -1, i.e. device + unresponsive. + The error is unrecoverable thus the device must be restarted to + restore its functionality. + + This attribute is available only when the kernel is built with + CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION=y. + + A write of 1 enables error injection. + + The following example shows how to enable error injection:: + + # cd /sys/kernel/debug/qat__ + # echo 1 > heartbeat/inject_error --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/ima_policy +++ linux-xilinx-6.8.0/Documentation/ABI/testing/ima_policy @@ -26,7 +26,7 @@ [uid=] [euid=] [gid=] [egid=] [fowner=] [fgroup=]] lsm: [[subj_user=] [subj_role=] [subj_type=] - [obj_user=] [obj_role=] [obj_type=]] + [obj_user=] [obj_role=] [obj_type=] [lsm=]] option: [digest_type=] [template=] [permit_directio] [appraise_type=] [appraise_flag=] [appraise_algos=] [keyrings=] @@ -138,6 +138,12 @@ measure subj_user=_ func=FILE_CHECK mask=MAY_READ + It is possible to explicitly specify which security + module a rule applies to using lsm=. If the security + module specified is not active on the system the rule + will be rejected. If lsm= is not specified the first + security module registered on the system will be assumed. + Example of measure rules using alternate PCRs:: measure func=KEXEC_KERNEL_CHECK pcr=4 --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev +++ linux-xilinx-6.8.0/Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev @@ -0,0 +1,9 @@ +What: /sys/bus/platform/devices//always_powered_in_suspend +Date: June 2022 +KernelVersion: 5.20 +Contact: Matthias Kaehlcke + linux-usb@vger.kernel.org +Description: + (RW) Controls whether the USB hub remains always powered + during system suspend or not. This attribute is not + available for non-hub devices. --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/sysfs-class-fpga-bridge +++ linux-xilinx-6.8.0/Documentation/ABI/testing/sysfs-class-fpga-bridge @@ -9,3 +9,12 @@ KernelVersion: 4.5 Contact: Alan Tull Description: Show bridge state as "enabled" or "disabled" + +What: /sys/class/fpga_bridge//set +Date: January 2017 +KernelVersion: 4.9 +Contact: Michal Simek +Description: Manual set bridge state (0-disable, !0 enable). + Enabling this option requires that the module is + compiled with #define DEBUG which is enabled by default + when CONFIG_DEBUG_KERNEL is setup. --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/sysfs-devices-system-cpu +++ linux-xilinx-6.8.0/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -516,6 +516,7 @@ /sys/devices/system/cpu/vulnerabilities/mds /sys/devices/system/cpu/vulnerabilities/meltdown /sys/devices/system/cpu/vulnerabilities/mmio_stale_data + /sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling /sys/devices/system/cpu/vulnerabilities/retbleed /sys/devices/system/cpu/vulnerabilities/spec_store_bypass /sys/devices/system/cpu/vulnerabilities/spectre_v1 --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/sysfs-driver-qat +++ linux-xilinx-6.8.0/Documentation/ABI/testing/sysfs-driver-qat @@ -141,3 +141,23 @@ 64 This attribute is only available for qat_4xxx devices. + +What: /sys/bus/pci/devices//qat/auto_reset +Date: March 2024 +KernelVersion: 6.8 +Contact: qat-linux@intel.com +Description: (RW) Reports the current state of the autoreset feature + for a QAT device + + Write to the attribute to enable or disable device auto reset. + + Device auto reset is disabled by default. + + The values are: + + * 1/Yy/on: auto reset enabled. If the device encounters an + unrecoverable error, it will be reset automatically. + * 0/Nn/off: auto reset disabled. If the device encounters an + unrecoverable error, it will not be reset. + + This attribute is only available for qat_4xxx devices. --- linux-xilinx-6.8.0.orig/Documentation/ABI/testing/sysfs-driver-xilsem-edac +++ linux-xilinx-6.8.0/Documentation/ABI/testing/sysfs-driver-xilsem-edac @@ -0,0 +1,104 @@ +What: /sys/devices/system/edac/versal_xilsem/xsem_scan_control +Date: Jan, 2023 +Contact: rama.devi.veggalam@amd.com +Description: + It is a read/write file. + Writing to this file causes the software to initiate a + request to the firmware for doing requested scan operation in + Configuration RAM (CRAM) or NPI of Versal devices. User needs + to provide scan operation id (init, start, stop) details. + The scan operation id values are as given below: + 1 - Initialize the scan + 2 - Start CRAM scan + 3 - Stop CRAM scan + 5 - Start NPI scan + 6 - Stop NPI scan + 7 - Inject NPI error in first descriptor + + When read, it shows the current scan status with error code. + The format is <0x1030 | operation Id> . + The different error codes are as given below: + ========== ===== + Error Code Cause + ========== ===== + 0x0 Scan operation success + 0x1 Failure in NPI scan + 0x80 Calibration timeout + 0x2000 Internal error + 0x500000 CRAM initialization not yet done + 0x600000 Start scan failed + 0x700000 Stop scan failed + 0xF00000 Active CRC/UE error + 0x1000000 ECC/CRC error detected during calibration + ========== ===== + +What: /sys/devices/system/edac/versal_xilsem/xsem_cram_injecterr +Date: Jan, 2023 +Contact: rama.devi.veggalam@amd.com +Description: + It is a read/write file. + Writing to this file causes the software to initiate a + request to the firmware for doing error injection in + Configuration RAM (CRAM) of Versal devices. User needs + to provide the location details of CRAM + (frame, qword, bit number, row number) to inject the error. + When read, it shows the current error injection status. The + format is
. + Example: 0x10304 0 + The different error codes are as given below: + ========== ===== + Error Code Cause + ========== ===== + 0x0 Error injection success + 0x2000 Internal NULL pointer error + 0x500000 CRAM initialization not yet done + 0x800000 Invalid row + 0x900000 Invalid qword + 0xA00000 Invalid bit + 0xB00000 Invalid frame address + 0xC00000 Unexpected bits flipped + 0xD00000 Masked bit + 0xE00000 Invalid block type + 0xF00000 Active CRC/UE error in CRAM + ========== ===== + +What: /sys/devices/system/edac/versal_xilsem/xsem_cram_framecc_read +Date: Jan, 2023 +Contact: rama.devi.veggalam@amd.com +Description: + It is a read/write file. + Writing to this file causes the software to initiate a + request to the firmware for reading frame ECC values in + Configuration RAM (CRAM) of Versal devices. User needs + to provide the location details of CRAM + (frame, row number) to read the ECC values. + When read, it shows the ECC values for the requested frame. + The format is
+ Example: 0 0x1030A 0x363B1A 0x8A0200 + +What: /sys/devices/system/edac/versal_xilsem/xsem_read_config +Date: Jan, 2023 +Contact: rama.devi.veggalam@amd.com +Description: + It is a read/write file. + Writing to this file causes the software to initiate a + request to the firmware for reading Xilsem configuration. + When read, it shows the CRAM and NPI scan configuration. + The format is
+ Example: 0 0x1030A 0x26 0x5016 + +What: /sys/devices/system/edac/versal_xilsem/xsem_read_status +Date: Jan, 2023 +Contact: rama.devi.veggalam@amd.com +Description: + It is a read/write file. + Writing to this file causes the software to initiate a + request read the Xilsem status. User needs to provide + the module id for status. The module id values are as given below: + 1 - CRAM scan + 2 - NPI scan + When read, it shows the status of the requested module. + For CRAM: + Example: 0x10005 0 + For NPI: + Example: 0xA01 0x10 0x1 --- linux-xilinx-6.8.0.orig/Documentation/Makefile +++ linux-xilinx-6.8.0/Documentation/Makefile @@ -111,8 +111,10 @@ $(YNL_RST_DIR)/%.rst: $(YNL_YAML_DIR)/%.yaml $(YNL_TOOL) $(Q)$(YNL_TOOL) -i $< -o $@ -htmldocs: $(YNL_INDEX) - @$(srctree)/scripts/sphinx-pre-install --version-check +htmldocs texinfodocs latexdocs epubdocs xmldocs: $(YNL_INDEX) + +htmldocs: + @$(srctree)/scripts/sphinx-pre-install --version-check --no-virtualenv @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var))) # If Rust support is available and .config exists, add rustdoc generated contents. --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/cifs/usage.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/cifs/usage.rst @@ -723,40 +723,26 @@ ======================= ======================================================= SecurityFlags Flags which control security negotiation and also packet signing. Authentication (may/must) - flags (e.g. for NTLM and/or NTLMv2) may be combined with + flags (e.g. for NTLMv2) may be combined with the signing flags. Specifying two different password hashing mechanisms (as "must use") on the other hand does not make much sense. Default flags are:: - 0x07007 + 0x00C5 - (NTLM, NTLMv2 and packet signing allowed). The maximum - allowable flags if you want to allow mounts to servers - using weaker password hashes is 0x37037 (lanman, - plaintext, ntlm, ntlmv2, signing allowed). Some - SecurityFlags require the corresponding menuconfig - options to be enabled. Enabling plaintext - authentication currently requires also enabling - lanman authentication in the security flags - because the cifs module only supports sending - laintext passwords using the older lanman dialect - form of the session setup SMB. (e.g. for authentication - using plain text passwords, set the SecurityFlags - to 0x30030):: + (NTLMv2 and packet signing allowed). Some SecurityFlags + may require enabling a corresponding menuconfig option. may use packet signing 0x00001 must use packet signing 0x01001 - may use NTLM (most common password hash) 0x00002 - must use NTLM 0x02002 may use NTLMv2 0x00004 must use NTLMv2 0x04004 - may use Kerberos security 0x00008 - must use Kerberos 0x08008 - may use lanman (weak) password hash 0x00010 - must use lanman password hash 0x10010 - may use plaintext passwords 0x00020 - must use plaintext passwords 0x20020 - (reserved for future packet encryption) 0x00040 + may use Kerberos security (krb5) 0x00008 + must use Kerberos 0x08008 + may use NTLMSSP 0x00080 + must use NTLMSSP 0x80080 + seal (packet encryption) 0x00040 + must seal (not implemented yet) 0x40040 cifsFYI If set to non-zero value, additional debug information will be logged to the system error log. This field --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/hw-vuln/core-scheduling.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/hw-vuln/core-scheduling.rst @@ -67,8 +67,8 @@ will be performed for all tasks in the task group of ``pid``. arg5: - userspace pointer to an unsigned long for storing the cookie returned by - ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands. + userspace pointer to an unsigned long long for storing the cookie returned + by ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands. In order for a process to push a cookie to, or pull a cookie from a process, it is required to have the ptrace access mode: `PTRACE_MODE_READ_REALCREDS` to the --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/hw-vuln/index.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/hw-vuln/index.rst @@ -21,3 +21,4 @@ cross-thread-rsb srso gather_data_sampling + reg-file-data-sampling --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst @@ -0,0 +1,104 @@ +================================== +Register File Data Sampling (RFDS) +================================== + +Register File Data Sampling (RFDS) is a microarchitectural vulnerability that +only affects Intel Atom parts(also branded as E-cores). RFDS may allow +a malicious actor to infer data values previously used in floating point +registers, vector registers, or integer registers. RFDS does not provide the +ability to choose which data is inferred. CVE-2023-28746 is assigned to RFDS. + +Affected Processors +=================== +Below is the list of affected Intel processors [#f1]_: + + =================== ============ + Common name Family_Model + =================== ============ + ATOM_GOLDMONT 06_5CH + ATOM_GOLDMONT_D 06_5FH + ATOM_GOLDMONT_PLUS 06_7AH + ATOM_TREMONT_D 06_86H + ATOM_TREMONT 06_96H + ALDERLAKE 06_97H + ALDERLAKE_L 06_9AH + ATOM_TREMONT_L 06_9CH + RAPTORLAKE 06_B7H + RAPTORLAKE_P 06_BAH + ATOM_GRACEMONT 06_BEH + RAPTORLAKE_S 06_BFH + =================== ============ + +As an exception to this table, Intel Xeon E family parts ALDERLAKE(06_97H) and +RAPTORLAKE(06_B7H) codenamed Catlow are not affected. They are reported as +vulnerable in Linux because they share the same family/model with an affected +part. Unlike their affected counterparts, they do not enumerate RFDS_CLEAR or +CPUID.HYBRID. This information could be used to distinguish between the +affected and unaffected parts, but it is deemed not worth adding complexity as +the reporting is fixed automatically when these parts enumerate RFDS_NO. + +Mitigation +========== +Intel released a microcode update that enables software to clear sensitive +information using the VERW instruction. Like MDS, RFDS deploys the same +mitigation strategy to force the CPU to clear the affected buffers before an +attacker can extract the secrets. This is achieved by using the otherwise +unused and obsolete VERW instruction in combination with a microcode update. +The microcode clears the affected CPU buffers when the VERW instruction is +executed. + +Mitigation points +----------------- +VERW is executed by the kernel before returning to user space, and by KVM +before VMentry. None of the affected cores support SMT, so VERW is not required +at C-state transitions. + +New bits in IA32_ARCH_CAPABILITIES +---------------------------------- +Newer processors and microcode update on existing affected processors added new +bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate +vulnerability and mitigation capability: + +- Bit 27 - RFDS_NO - When set, processor is not affected by RFDS. +- Bit 28 - RFDS_CLEAR - When set, processor is affected by RFDS, and has the + microcode that clears the affected buffers on VERW execution. + +Mitigation control on the kernel command line +--------------------------------------------- +The kernel command line allows to control RFDS mitigation at boot time with the +parameter "reg_file_data_sampling=". The valid arguments are: + + ========== ================================================================= + on If the CPU is vulnerable, enable mitigation; CPU buffer clearing + on exit to userspace and before entering a VM. + off Disables mitigation. + ========== ================================================================= + +Mitigation default is selected by CONFIG_MITIGATION_RFDS. + +Mitigation status information +----------------------------- +The Linux kernel provides a sysfs interface to enumerate the current +vulnerability status of the system: whether the system is vulnerable, and +which mitigations are active. The relevant sysfs file is: + + /sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling + +The possible values in this file are: + + .. list-table:: + + * - 'Not affected' + - The processor is not vulnerable + * - 'Vulnerable' + - The processor is vulnerable, but no mitigation enabled + * - 'Vulnerable: No microcode' + - The processor is vulnerable but microcode is not updated. + * - 'Mitigation: Clear Register File' + - The processor is vulnerable and the CPU buffer clearing mitigation is + enabled. + +References +---------- +.. [#f1] Affected Processors + https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/hw-vuln/spectre.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/hw-vuln/spectre.rst @@ -138,11 +138,10 @@ the BHB might be shared across privilege levels even in the presence of Enhanced IBRS. -Currently the only known real-world BHB attack vector is via -unprivileged eBPF. Therefore, it's highly recommended to not enable -unprivileged eBPF, especially when eIBRS is used (without retpolines). -For a full mitigation against BHB attacks, it's recommended to use -retpolines (or eIBRS combined with retpolines). +Previously the only known real-world BHB attack vector was via unprivileged +eBPF. Further research has found attacks that don't require unprivileged eBPF. +For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or +use the BHB clearing sequence. Attack scenarios ---------------- @@ -430,6 +429,23 @@ 'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB =========================== ======================================================= + - Branch History Injection (BHI) protection status: + +.. list-table:: + + * - BHI: Not affected + - System is not affected + * - BHI: Retpoline + - System is protected by retpoline + * - BHI: BHI_DIS_S + - System is protected by BHI_DIS_S + * - BHI: SW loop, KVM SW loop + - System is protected by software clearing sequence + * - BHI: Vulnerable + - System is vulnerable to BHI + * - BHI: Vulnerable, KVM: SW loop + - System is vulnerable; KVM is protected by software clearing sequence + Full mitigation might require a microcode update from the CPU vendor. When the necessary microcode is not available, the kernel will report vulnerability. @@ -484,7 +500,11 @@ Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at boot, by setting the IBRS bit, and they're automatically protected against - Spectre v2 variant attacks. + some Spectre v2 variant attacks. The BHB can still influence the choice of + indirect branch predictor entry, and although branch predictor entries are + isolated between modes when eIBRS is enabled, the BHB itself is not isolated + between modes. Systems which support BHI_DIS_S will set it to protect against + BHI attacks. On Intel's enhanced IBRS systems, this includes cross-thread branch target injections on SMT systems (STIBP). In other words, Intel eIBRS enables @@ -638,6 +658,18 @@ spectre_v2=off. Spectre variant 1 mitigations cannot be disabled. + spectre_bhi= + + [X86] Control mitigation of Branch History Injection + (BHI) vulnerability. This setting affects the deployment + of the HW BHI control and the SW BHB clearing sequence. + + on + (default) Enable the HW or SW mitigation as + needed. + off + Disable the mitigation. + For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt Mitigation selection guide --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/kernel-parameters.txt +++ linux-xilinx-6.8.0/Documentation/admin-guide/kernel-parameters.txt @@ -848,6 +848,10 @@ Format: ,,,[,] + cpufreq_driver= [X86] Allow only the named cpu frequency scaling driver + to register. Example: cpufreq_driver=powernow-k8 + Format: { none | STRING } + cpuidle.off=1 [CPU_IDLE] disable the cpuidle sub-system @@ -1150,6 +1154,26 @@ The filter can be disabled or changed to another driver later using sysfs. + reg_file_data_sampling= + [X86] Controls mitigation for Register File Data + Sampling (RFDS) vulnerability. RFDS is a CPU + vulnerability which may allow userspace to infer + kernel data values previously stored in floating point + registers, vector registers, or integer registers. + RFDS only affects Intel Atom processors. + + on: Turns ON the mitigation. + off: Turns OFF the mitigation. + + This parameter overrides the compile time default set + by CONFIG_MITIGATION_RFDS. Mitigation cannot be + disabled when other VERW based mitigations (like MDS) + are enabled. In order to disable RFDS mitigation all + VERW based mitigations need to be disabled. + + For details see: + Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst + driver_async_probe= [KNL] List of driver names to be probed asynchronously. * matches with all driver names. If * is specified, the @@ -3320,9 +3344,7 @@ mem_encrypt= [X86-64] AMD Secure Memory Encryption (SME) control Valid arguments: on, off - Default (depends on kernel configuration option): - on (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) - off (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=n) + Default: off mem_encrypt=on: Activate SME mem_encrypt=off: Do not activate SME @@ -3381,6 +3403,9 @@ arch-independent options, each of which is an aggregation of existing arch-specific options. + Note, "mitigations" is supported if and only if the + kernel was built with CPU_MITIGATIONS=y. + off Disable all optional CPU mitigations. This improves system performance, but it may also @@ -3398,8 +3423,10 @@ nospectre_bhb [ARM64] nospectre_v1 [X86,PPC] nospectre_v2 [X86,PPC,S390,ARM64] + reg_file_data_sampling=off [X86] retbleed=off [X86] spec_store_bypass_disable=off [X86,PPC] + spectre_bhi=off [X86] spectre_v2_user=off [X86] srbds=off [X86,INTEL] ssbd=force-off [ARM64] @@ -4370,6 +4397,12 @@ nomsi [MSI] If the PCI_MSI kernel config parameter is enabled, this kernel boot option can be used to disable the use of MSI interrupts system-wide. + clearmsi [X86] Clears MSI/MSI-X enable bits early in boot + time in order to avoid issues like adapters + screaming irqs and preventing boot progress. + Also, it enforces the PCI Local Bus spec + rule that those bits should be 0 in system reset + events (useful for kexec/kdump cases). noioapicquirk [APIC] Disable all boot interrupt quirks. Safety option to keep boot IRQs enabled. This should never be necessary. @@ -5034,6 +5067,11 @@ this kernel boot parameter, forcibly setting it to zero. + rcutree.enable_rcu_lazy= [KNL] + To save power, batch RCU callbacks and flush after + delay, memory pressure or callback list growing too + big. + rcuscale.gp_async= [KNL] Measure performance of asynchronous grace-period primitives such as call_rcu(). @@ -6012,6 +6050,15 @@ sonypi.*= [HW] Sony Programmable I/O Control Device driver See Documentation/admin-guide/laptops/sonypi.rst + spectre_bhi= [X86] Control mitigation of Branch History Injection + (BHI) vulnerability. This setting affects the + deployment of the HW BHI control and the SW BHB + clearing sequence. + + on - (default) Enable the HW or SW mitigation + as needed. + off - Disable the mitigation. + spectre_v2= [X86] Control mitigation of Spectre variant 2 (indirect branch speculation) vulnerability. The default operation protects the kernel from --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/mm/damon/usage.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/mm/damon/usage.rst @@ -450,7 +450,7 @@ # # further filter out all cgroups except one at '/having_care_already' echo memcg > 1/type echo /having_care_already > 1/memcg_path - echo N > 1/matching + echo Y > 1/matching Note that ``anon`` and ``memcg`` filters are currently supported only when ``paddr`` :ref:`implementation ` is being used. --- linux-xilinx-6.8.0.orig/Documentation/admin-guide/sysctl/net.rst +++ linux-xilinx-6.8.0/Documentation/admin-guide/sysctl/net.rst @@ -206,6 +206,11 @@ Default: 0 (off) +mem_pcpu_rsv +------------ + +Per-cpu reserved forward alloc cache size in page units. Default 1MB per CPU. + rmem_default ------------ --- linux-xilinx-6.8.0.orig/Documentation/arch/powerpc/kvm-nested.rst +++ linux-xilinx-6.8.0/Documentation/arch/powerpc/kvm-nested.rst @@ -546,7 +546,9 @@ +--------+-------+----+--------+----------------------------------+ | 0x1052 | 0x08 | RW | T | CTRL | +--------+-------+----+--------+----------------------------------+ -| 0x1053-| | | | Reserved | +| 0x1053 | 0x08 | RW | T | DPDES | ++--------+-------+----+--------+----------------------------------+ +| 0x1054-| | | | Reserved | | 0x1FFF | | | | | +--------+-------+----+--------+----------------------------------+ | 0x2000 | 0x04 | RW | T | CR | --- linux-xilinx-6.8.0.orig/Documentation/arch/x86/amd-memory-encryption.rst +++ linux-xilinx-6.8.0/Documentation/arch/x86/amd-memory-encryption.rst @@ -87,14 +87,14 @@ kernel is non-zero). SME can also be enabled and activated in the BIOS. If SME is enabled and -activated in the BIOS, then all memory accesses will be encrypted and it will -not be necessary to activate the Linux memory encryption support. If the BIOS -merely enables SME (sets bit 23 of the MSR_AMD64_SYSCFG), then Linux can activate -memory encryption by default (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) or -by supplying mem_encrypt=on on the kernel command line. However, if BIOS does -not enable SME, then Linux will not be able to activate memory encryption, even -if configured to do so by default or the mem_encrypt=on command line parameter -is specified. +activated in the BIOS, then all memory accesses will be encrypted and it +will not be necessary to activate the Linux memory encryption support. + +If the BIOS merely enables SME (sets bit 23 of the MSR_AMD64_SYSCFG), +then memory encryption can be enabled by supplying mem_encrypt=on on the +kernel command line. However, if BIOS does not enable SME, then Linux +will not be able to activate memory encryption, even if configured to do +so by default or the mem_encrypt=on command line parameter is specified. Secure Nested Paging (SNP) ========================== --- linux-xilinx-6.8.0.orig/Documentation/cdrom/cdrom-standard.rst +++ linux-xilinx-6.8.0/Documentation/cdrom/cdrom-standard.rst @@ -217,7 +217,7 @@ int (*media_changed)(struct cdrom_device_info *, int); int (*tray_move)(struct cdrom_device_info *, int); int (*lock_door)(struct cdrom_device_info *, int); - int (*select_speed)(struct cdrom_device_info *, int); + int (*select_speed)(struct cdrom_device_info *, unsigned long); int (*get_last_session) (struct cdrom_device_info *, struct cdrom_multisession *); int (*get_mcn)(struct cdrom_device_info *, struct cdrom_mcn *); @@ -396,7 +396,7 @@ :: - int select_speed(struct cdrom_device_info *cdi, int speed) + int select_speed(struct cdrom_device_info *cdi, unsigned long speed) Some CD-ROM drives are capable of changing their head-speed. There are several reasons for changing the speed of a CD-ROM drive. Badly --- linux-xilinx-6.8.0.orig/Documentation/cgroups/namespace.txt +++ linux-xilinx-6.8.0/Documentation/cgroups/namespace.txt @@ -0,0 +1,142 @@ + CGroup Namespaces + +CGroup Namespace provides a mechanism to virtualize the view of the +/proc//cgroup file. The CLONE_NEWCGROUP clone-flag can be used with +clone() and unshare() syscalls to create a new cgroup namespace. +The process running inside the cgroup namespace will have its /proc//cgroup +output restricted to cgroupns-root. cgroupns-root is the cgroup of the process +at the time of creation of the cgroup namespace. + +Prior to CGroup Namespace, the /proc//cgroup file used to show complete +path of the cgroup of a process. In a container setup (where a set of cgroups +and namespaces are intended to isolate processes), the /proc//cgroup file +may leak potential system level information to the isolated processes. + +For Example: + $ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1 + +The path '/batchjobs/container_id1' can generally be considered as system-data +and its desirable to not expose it to the isolated process. + +CGroup Namespaces can be used to restrict visibility of this path. +For Example: + # Before creating cgroup namespace + $ ls -l /proc/self/ns/cgroup + lrwxrwxrwx 1 root root 0 2014-07-15 10:37 /proc/self/ns/cgroup -> cgroup:[4026531835] + $ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1 + + # unshare(CLONE_NEWCGROUP) and exec /bin/bash + $ ~/unshare -c + [ns]$ ls -l /proc/self/ns/cgroup + lrwxrwxrwx 1 root root 0 2014-07-15 10:35 /proc/self/ns/cgroup -> cgroup:[4026532183] + # From within new cgroupns, process sees that its in the root cgroup + [ns]$ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/ + + # From global cgroupns: + $ cat /proc//cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1 + + # Unshare cgroupns along with userns and mountns + # Following calls unshare(CLONE_NEWCGROUP|CLONE_NEWUSER|CLONE_NEWNS), then + # sets up uid/gid map and execs /bin/bash + $ ~/unshare -c -u -m + # Originally, we were in /batchjobs/container_id1 cgroup. Mount our own cgroup + # hierarchy. + [ns]$ mount -t cgroup cgroup /tmp/cgroup + [ns]$ ls -l /tmp/cgroup + total 0 + -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.controllers + -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.populated + -rw-r--r-- 1 root root 0 2014-10-13 09:25 cgroup.procs + -rw-r--r-- 1 root root 0 2014-10-13 09:32 cgroup.subtree_control + +The cgroupns-root (/batchjobs/container_id1 in above example) becomes the +filesystem root for the namespace specific cgroupfs mount. + +The virtualization of /proc/self/cgroup file combined with restricting +the view of cgroup hierarchy by namespace-private cgroupfs mount +should provide a completely isolated cgroup view inside the container. + +In its current form, the cgroup namespaces patcheset provides following +behavior: + +(1) The 'cgroupns-root' for a cgroup namespace is the cgroup in which + the process calling unshare is running. + For ex. if a process in /batchjobs/container_id1 cgroup calls unshare, + cgroup /batchjobs/container_id1 becomes the cgroupns-root. + For the init_cgroup_ns, this is the real root ('/') cgroup + (identified in code as cgrp_dfl_root.cgrp). + +(2) The cgroupns-root cgroup does not change even if the namespace + creator process later moves to a different cgroup. + $ ~/unshare -c # unshare cgroupns in some cgroup + [ns]$ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/ + [ns]$ mkdir sub_cgrp_1 + [ns]$ echo 0 > sub_cgrp_1/cgroup.procs + [ns]$ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1 + +(3) Each process gets its CGROUPNS specific view of /proc//cgroup +(a) Processes running inside the cgroup namespace will be able to see + cgroup paths (in /proc/self/cgroup) only inside their root cgroup + [ns]$ sleep 100000 & # From within unshared cgroupns + [1] 7353 + [ns]$ echo 7353 > sub_cgrp_1/cgroup.procs + [ns]$ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1 + +(b) From global cgroupns, the real cgroup path will be visible: + $ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1/sub_cgrp_1 + +(c) From a sibling cgroupns (cgroupns root-ed at a different cgroup), cgroup + path relative to its own cgroupns-root will be shown: + # ns2's cgroupns-root is at '/batchjobs/container_id2' + [ns2]$ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2/sub_cgrp_1 + + Note that the relative path always starts with '/' to indicate that its + relative to the cgroupns-root of the caller. + +(4) Processes inside a cgroupns can move in-and-out of the cgroupns-root + (if they have proper access to external cgroups). + # From inside cgroupns (with cgroupns-root at /batchjobs/container_id1), and + # assuming that the global hierarchy is still accessible inside cgroupns: + $ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1 + $ echo 7353 > batchjobs/container_id2/cgroup.procs + $ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2 + + Note that this kind of setup is not encouraged. A task inside cgroupns + should only be exposed to its own cgroupns hierarchy. Otherwise it makes + the virtualization of /proc//cgroup less useful. + +(5) Setns to another cgroup namespace is allowed when: + (a) the process has CAP_SYS_ADMIN in its current userns + (b) the process has CAP_SYS_ADMIN in the target cgroupns' userns + No implicit cgroup changes happen with attaching to another cgroupns. It + is expected that the somone moves the attaching process under the target + cgroupns-root. + +(6) When some thread from a multi-threaded process unshares its + cgroup-namespace, the new cgroupns gets applied to the entire process (all + the threads). For the unified-hierarchy this is expected as it only allows + process-level containerization. For the legacy hierarchies this may be + unexpected. So all the threads in the process will have the same cgroup. + +(7) The cgroup namespace is alive as long as there is atleast 1 + process inside it. When the last process exits, the cgroup + namespace is destroyed. The cgroupns-root and the actual cgroups + remain though. + +(8) Namespace specific cgroup hierarchy can be mounted by a process running + inside cgroupns: + $ mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT + + This will mount the unified cgroup hierarchy with cgroupns-root as the + filesystem root. The process needs CAP_SYS_ADMIN in its userns and mntns. --- linux-xilinx-6.8.0.orig/Documentation/conf.py +++ linux-xilinx-6.8.0/Documentation/conf.py @@ -346,9 +346,9 @@ html_static_path = ['sphinx-static'] # If true, Docutils "smart quotes" will be used to convert quotes and dashes -# to typographically correct entities. This will convert "--" to "—", -# which is not always what we want, so disable it. -smartquotes = False +# to typographically correct entities. However, conversion of "--" to "—" +# is not always what we want, so enable only quotes. +smartquotes_action = 'q' # Custom sidebar templates, maps document names to template names. # Note that the RTD theme ignores this --- linux-xilinx-6.8.0.orig/Documentation/dev-tools/ubsan.rst +++ linux-xilinx-6.8.0/Documentation/dev-tools/ubsan.rst @@ -49,34 +49,22 @@ Usage ----- -To enable UBSAN configure kernel with:: +To enable UBSAN, configure the kernel with:: - CONFIG_UBSAN=y + CONFIG_UBSAN=y -and to check the entire kernel:: - - CONFIG_UBSAN_SANITIZE_ALL=y - -To enable instrumentation for specific files or directories, add a line -similar to the following to the respective kernel Makefile: - -- For a single file (e.g. main.o):: - - UBSAN_SANITIZE_main.o := y - -- For all files in one directory:: - - UBSAN_SANITIZE := y - -To exclude files from being instrumented even if -``CONFIG_UBSAN_SANITIZE_ALL=y``, use:: +To exclude files from being instrumented use:: UBSAN_SANITIZE_main.o := n -and:: +and to exclude all targets in one directory use:: UBSAN_SANITIZE := n +When disabled for all targets, specific files can be enabled using:: + + UBSAN_SANITIZE_main.o := y + Detection of unaligned accesses controlled through the separate option - CONFIG_UBSAN_ALIGNMENT. It's off by default on architectures that support unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/arm/zynq/zynq-efuse.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/arm/zynq/zynq-efuse.txt @@ -0,0 +1,15 @@ +Device tree bindings for Zynq's eFuse Controller + +The Zynq eFuse controller provides the access to the chip efuses which contain +information about device DNA, security settings and also device status. + +Required properties: + compatible: Compatibility string. Must be "xlnx,zynq-efuse". + reg: Specify the base and size of the EFUSE controller registers + in the memory map. E.g.: reg = <0xf800d000 0x20>; + +Example: +efuse: efuse@f800d000 { + compatible = "xlnx,zynq-efuse"; + reg = <0xf800d000 0x20>; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/cache/qcom,llcc.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/cache/qcom,llcc.yaml @@ -66,7 +66,6 @@ compatible: contains: enum: - - qcom,qdu1000-llcc - qcom,sc7180-llcc - qcom,sm6350-llcc then: @@ -104,6 +103,7 @@ compatible: contains: enum: + - qcom,qdu1000-llcc - qcom,sc8180x-llcc - qcom,sc8280xp-llcc - qcom,x1e80100-llcc --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/clock/idt,idt8t49n24x.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/clock/idt,idt8t49n24x.txt @@ -0,0 +1,156 @@ +Binding for IDT 8T49N24x Universal Frequency Translator + +The 8T49N241 has one fractional-feedback PLL that can be used as a +jitter attenuator and frequency translator. It is equipped with one +integer and three fractional output dividers, allowing the generation +of up to four different output frequencies, ranging from 8kHz to 1GHz. +These frequencies are completely independent of each other, the input +reference frequencies and the crystal reference frequency. The device +places virtually no constraints on input to output frequency conversion, +supporting all FEC rates, including the new revision of ITU-T +Recommendation G.709 (2009), most with 0ppm conversion error. +The outputs may select among LVPECL, LVDS, HCSL or LVCMOS output levels. + +The driver can read a full register map from the DT, and will use that +register map to initialize the attached part (via I2C) when the system +boots. Any configuration not supported by the common clock framework +must be done via the full register map, including optimized settings. + +The 8T49N241 accepts up to two differential or single-ended input clocks +and a fundamental-mode crystal input. The internal PLL can lock to either +of the input reference clocks or just to the crystal to behave as a +frequency synthesizer. The PLL can use the second input for redundant +backup of the primary input reference, but in this case, both input clock +references must be related in frequency. + +All outputs are currently assumed to be LVDS, unless overridden in the +full register map in the DT. + +==I2C device node== + +Required properties: +- compatible: shall be one of "idt,idt8t49n241" +- reg: i2c device address, shall be one of 0x7C, 0x6C, 0x7D, 0x6D, + 0x7E, 0x6E, 0x7F, 0x6F. +- #clock-cells: From common clock bindings: Shall be 1. + +- clocks: from common clock binding; input clock handle. Required. +- clock-names: from common clock binding; clock input names, shall be + one of "input-clk0", "input-clk1", "input-xtal". Required. + +==Mapping between clock specifier and physical pins== + +When referencing the provided clock in the DT using phandle and +clock specifier, the following mapping applies: + +8T49N241: + 0 -- Q0 + 1 -- Q1 + 2 -- Q2 + 3 -- Q3 + +==Example== + +/* Example1: 25MHz input clock (via CLK0) */ + +ref25: ref25m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; +}; + +i2c-master-node { + + /* IDT 8T49N241 i2c universal frequency translator */ + i2c241: clock-generator@6a { + compatible = "idt,idt8t49n241"; + reg = <0x6c>; + #clock-cells = <1>; + + /* Connect input-clk0 to 25MHz reference */ + clocks = <&ref25m>; + clock-names = "input-clk0"; + }; +}; + +/* Consumer referencing the 8T49N241 pin Q1 */ +consumer { + ... + clocks = <&i2c241 1>; + ... +} + +/* Example2: 40MHz xtal frequency, specify all settings */ + +ref40: ref40m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <40000000>; +}; + +i2c-master-node { + + /* IDT 8T49N241 i2c universal frequency translator */ + i2c241: clock-generator@6a { + compatible = "idt,idt8t49n241"; + reg = <0x6c>; + #clock-cells = <1>; + + /* Connect input-xtal to 40MHz reference */ + clocks = <&ref40m>; + clock-names = "input-xtal"; + + settings=[ +09 50 00 60 67 C5 6C FF 03 00 30 00 00 01 00 00 +01 07 00 00 07 00 00 77 6D 06 00 00 00 00 00 FF +FF FF FF 00 3F 00 2A 00 16 33 33 00 01 00 00 D0 +00 00 00 00 00 00 00 00 00 04 00 00 00 02 00 00 +00 00 00 00 00 00 00 17 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 D7 0A 2B 20 00 00 00 0B +00 00 00 00 00 00 00 00 00 00 27 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +C3 00 08 01 00 00 00 00 00 00 00 00 00 30 00 00 +00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 85 00 00 9C 01 D4 02 71 07 00 00 00 +00 83 00 10 02 08 8C +]; + }; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/clock/renesas,proxo.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/clock/renesas,proxo.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/renesas,proxo.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas ProXO Oscillator + +maintainers: + - Alex Helms + +description: + Renesas ProXO is a family of programmable ultra-low phase noise + quartz-based oscillators. + +properties: + '#clock-cells': + const: 0 + + compatible: + enum: + - renesas,proxo-xp + + reg: + maxItems: 1 + + renesas,crystal-frequency: + description: Internal crystal frequency, default is 50000000 (50MHz) + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - '#clock-cells' + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + proxo: clock-controller@55 { + compatible = "renesas,proxo-xp"; + reg = <0x55>; + #clock-cells = <0>; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/clock/silabs,si5324.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/clock/silabs,si5324.txt @@ -0,0 +1,78 @@ +Binding for Silicon Labs si5324, si5328 and si5319 programmable +I2C clock generator. + +Reference +This binding uses the common clock binding[1]. +The si5324 is programmable i2c low-bandwidth, jitter-attenuating, precision +clock multiplier with up to 2 output clocks. The internal structure can be +found in [2]. +The internal pin structure of si5328 and si5319 can be found in [3]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Si5324 Data Sheet + http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5324.pdf +[3] Si53xx Reference Manual + http://www.silabs.com/Support%20Documents/TechnicalDocs/ + Si53xxReferenceManual.pdf + +==I2C device node== + +Required properties: +- compatible: should be one of + "silabs,si5324" + "silabs,si5319" + "silabs,si5328" +- reg: i2c device address. +- #clock-cells: from common clock binding; shall be set to 1. +- clocks: from common clock binding; list of parent clock + handles, clock name should be one of + "xtal" + "clkin1" + "clkin2" +- #address-cells: shall be set to 1. +- #size-cells: shall be set to 0. + +Optional properties: +- silabs,pll-source: pair of (number, source) for each pll. Allows + to overwrite clock source of pll. + +==Child nodes== + +Each of the clock outputs can be overwritten individually by +using a child node to the I2C device node. If a child node for a clock +output is not set, the eeprom configuration is not overwritten. + +Required child node properties: +- reg: number of clock output. +- clock-frequency: default output frequency at power on + +Optional child node properties: +- silabs,drive-strength: output drive strength in mA, shall be one of {2,4,6,8}. + +Example: +Following example describes the ZCU102 board with hdmi design which +uses si5319 as clock generator. XTAL is hard-wired on the board to act +as input clock with a frequency of 114.285MHz. + +refhdmi: refhdmi { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <114285000>; +}; + +/* Si5319 i2c clock generator */ +si5319: clock-generator@68 { + status = "okay"; + compatible = "silabs,si5319"; + reg = <0x68>; + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + clocks = <&refhdmi>; + clock-names = "xtal"; + + clk0 { + reg = <0>; + clock-frequency = <27000000>; + }; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/clock/xlnx,vcu.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/clock/xlnx,vcu.txt @@ -0,0 +1,33 @@ +LogicoreIP designed compatible with Xilinx ZYNQ family. +------------------------------------------------------- + +General concept +--------------- + +LogicoreIP design to provide the isolation between processing system +and programmable logic. Also provides the list of register set to configure +the frequency. + +Required properties: +- compatible: shall be one of: + "xlnx,vcu" + "xlnx,vcu-logicoreip-1.0" +- reg : The base offset and size of the VCU_PL_SLCR register space. +- clocks: phandle for aclk and pll_ref clocksource +- clock-names: The identification string, "aclk", is always required for + the axi clock. "pll_ref" is required for pll. + +Optional properties: +- reset-gpios : The GPIO used to reset the VCU, if available. Need use this + reset gpio when in design 'vcu_resetn' is driven by gpio. See + Documentation/devicetree/bindings/gpio/gpio.txt for details. + +Example: + + xlnx_vcu: vcu@a0040000 { + compatible = "xlnx,vcu-logicoreip-1.0"; + reg = <0x0 0xa0040000 0x0 0x1000>; + reset-gpios = <&gpio 0x4e GPIO_ACTIVE_HIGH>;t + clocks = <&si570_1>, <&clkc 71>; + clock-names = "pll_ref", "aclk"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/crypto/xlnx,zynqmp-aes.yaml @@ -10,6 +10,8 @@ - Kalyani Akula - Michal Simek +deprecated: true + description: | The ZynqMP AES-GCM hardened cryptographic accelerator is used to encrypt or decrypt the data with provided key and initialization vector. --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/crypto/zynqmp-rsa.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/crypto/zynqmp-rsa.txt @@ -0,0 +1,12 @@ +Xilinx ZynqMP RSA hw acceleration support + +The zynqmp PS-RSA hw accelerator is used to encrypt/decrypt +the given user data. + +Required properties: +- compatible: should contain "xlnx,zynqmp-rsa" (deprecated) + +Example: + xlnx_rsa: zynqmp_rsa { + compatible = "xlnx,zynqmp-rsa"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml @@ -127,6 +127,7 @@ - qcom,dsi-phy-20nm - qcom,dsi-phy-28nm-8226 - qcom,dsi-phy-28nm-hpm + - qcom,dsi-phy-28nm-hpm-fam-b - qcom,dsi-phy-28nm-lp - qcom,hdmi-phy-8084 - qcom,hdmi-phy-8660 --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml @@ -53,6 +53,15 @@ compatible: const: qcom,sm8150-dpu + "^displayport-controller@[0-9a-f]+$": + type: object + additionalProperties: true + + properties: + compatible: + contains: + const: qcom,sm8150-dp + "^dsi@[0-9a-f]+$": type: object additionalProperties: true --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/bridge.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/bridge.txt @@ -0,0 +1,29 @@ +Xilinx DRM bridge +----------------- + +The Xilinx DRM provides the interface layer called Xilinx bridge to bridge +multiple components with a series of functions. It models a simple +unidirectional communication, single client -> single bridge. The client +is not limited to DRM compatible drivers, but can be any subsystem driver, +but the client driver should call the bridge functions explicitly. + +Provider +-------- + +The bridge provider should assign a corresponding of_node to struct xlnx_bridge. +For example, if its own node is used, + + provider_node: provider_node { + }; + + bridge.of_node = provider_device->of_node; + +Client +------ + +The bridge client should have a phandle to the bridge device node. The bridge +device node should be passed to get a bridge instance, + + client_node { + xlnx,bridge = <&provider_node>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,dp-tx.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,dp-tx.yaml @@ -0,0 +1,225 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/xlnx/xlnx,dp-tx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx DisplayPort Transmitter Subsystem + +maintainers: + - Rajesh Gugulothu + +description: | + The Xilinx DisplayPort Tx Subsystem contains several subcores to implement + a DisplayPort Transmitter and outputs video data using DisplayPort protocol. + For more details, please refer to PG199 at + https://www.xilinx.com/support/documentation/ip_documentation/dp_tx_subsystem/v2_1/pg199-displayport-tx-subsystem.pdf + +properties: + compatible: + enum: + - xlnx,v-dp-txss-3.0 + - xlnx,v-dp-txss-3.1 + + reg: + maxItems: 2 + description: DisplayPort Transmitter Subsystem registers + + reg-names: + items: + - const: dp_base + - const: gt_quad_base + + interrupts: + minItems: 1 + maxItems: 4 + + interrupt-names: + description: Only dptxss_dp_irq is mandatory. Others are optional. + dptxss_timer_irq will be present when HDCP 1x or 2x is selected. + dptxss_hdcp_irq will be present when HDCP 1x is selected. + dptxss_hdcp22_cipher_irq will be present when HDCP 2x is selected. + items: + - const: dptxss_dp_irq + - const: dptxss_timer_irq + - const: dptxss_hdcp_irq + - const: dptxss_hdcp22_cipher_irq + + clocks: + description: List of clock specifiers + items: + - description: AXI Lite clock + - description: Video clock + + clock-names: + items: + - const: s_axi_aclk + - const: tx_vid_clk + + phys: + description: This denotes phandles for phy lanes registered + for DP protocol.DisplayPort always require 4 lanes + + phy-names: + items: + - const: dp-phy0 + - const: dp-phy1 + - const: dp-phy2 + - const: dp-phy3 + + xlnx,vtc-offset: + description: This denotes register offset address of VTC sub-core of + DisplayPort Transmitter Subsystem. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + + xlnx,max-lanes: + description: Max number of lanes that IP configured with. + Possible values are 1, 2, 4. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 4] + + xlnx,max-link-rate: + description: | + Max link rate that IP configured with.Possible values are as below - + 162000 - 1.6 Gb/s + 270000 - 2.7 Gb/s + 540000 - 5.4 Gb/s + 810000 - 8.1 Gb/s + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [162000, 270000, 540000, 810000] + + xlnx,bpc: + description: | + Max BPC value that IP configured with. For example if IP is configured + with 10 BPC means it supports (6, 8, 10) up to 10bpc. + Possible values are 6, 8, 10, 12, 16. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [6, 8, 10, 12, 16] + + xlnx,audio-channels: + description: | + This denotes number of audio channels enabled in the IP + configuration. Possible values are 2, 3, 4, 5, 6, 7, 8. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [2, 3, 4, 5, 6, 7, 8] + + xlnx,hdcp22-enable: + type: boolean + description: | + Present when HDCP2.2 is present in design. + + xlnx,hdcp-enable: + type: boolean + description: | + Present when HDCP1.4 is present in design. + + xlnx,versal-gt: + type: boolean + description: | + Boolean property present when versal GT is present in design. + + xlnx,xilinx-vfmc: + description: phandle of xilinx video FMC node + $ref: /schemas/types.yaml#/definitions/phandle + + ports: + type: object + + properties: + port@0: + type: object + description: | + Output / source port node, endpoint describing modules + connected the DisplayPort transmitter + + properties: + reg: + const: 0 + + endpoint: + type: object + + properties: + + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - reg-names + - interrupts + - clocks + - clock-names + - xlnx,max-link-rate + - xlnx,bpc + - xlnx,max-lanes + - phy-names + - phys + - ports + +additionalProperties: false + +if: + properties: + compatible: + contains: + const: xlnx,v-dp-txss-3.1 + +then: + required: + - xlnx,vtc-offset + +examples: + - | + bus { + #address-cells = <2>; + #size-cells = <2>; + + v_dp_txss1@a0100000 { + compatible = "xlnx,v-dp-txss-3.1"; + reg = <0x0 0xa0100000 0x0 0x40000>, <0x0 0xa4080000 0x0 0x10000>; + reg-names = "dp_base", "gt_quad_base"; + clock-names = "s_axi_aclk", "tx_vid_clk"; + clocks = <&zynqmp_clk 71>, <&si570_1>; + interrupt-names = "dptxss_dp_irq", "dptxss_timer_irq", "dptxss_hdcp_irq", + "dptxss_hdcp22_cipher_irq"; + interrupts = <0 92 4>, <0 108 4>, <0 111 4>, <0 109 4>; + xlnx,vtc-offset = <0x8000>; + xlnx,max-lanes = <4>; + xlnx,max-link-rate = <810000>; + xlnx,bpc = <8>; + xlnx,audio-channels = <2>; + xlnx,hdcp22-enable; + xlnx,hdcp-enable; + xlnx,versal-gt; + xlnx,xilinx-vfmc = <&xfmc>; + phy-names = "dp-phy0", "dp-phy1", "dp-phy2", "dp-phy3"; + phys = <&vphy_lane0 0 1 1 0>, <&vphy_lane1 0 1 1 0>, + <&vphy_lane2 0 1 1 0>, <&vphy_lane3 0 1 1 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dp_transmitter: endpoint { + remote-endpoint = <&display_controller>; + }; + }; + }; + }; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,dsi.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,dsi.txt @@ -0,0 +1,74 @@ +Device-Tree bindings for Xilinx MIPI DSI Tx IP core + +The IP core supports transmission of video data in MIPI DSI protocol. + +Required properties: + - compatible: Should be "xlnx,dsi". + + - reg: Base address and size of the IP core. + + - xlnx,dsi-datatype: Color format. The value should be one of "MIPI_DSI_FMT_RGB888", + "MIPI_DSI_FMT_RGB666", "MIPI_DSI_FMT_RGB666_PACKED" or "MIPI_DSI_FMT_RGB565". + + - simple_panel: The subnode for connected panel. This represents the + DSI peripheral connected to the DSI host node. Please refer to + Documentation/devicetree/bindings/display/mipi-dsi-bus.txt. The + simple-panel driver has auo,b101uan01 panel timing parameters added along + with other existing panels. DSI driver derive the required Tx IP controller + timing values from the panel timing parameters. + + - port: Logical block can be used / connected independently with + external device. In the display controller port nodes, topology + for entire pipeline should be described using the DT bindings defined in + Documentation/devicetree/bindings/graph.txt. + + - xlnx,dsi-num-lanes: Possible number of DSI lanes for the Tx controller. + The values should be 1, 2, 3 or 4. Based on xlnx,dsi-num-lanes and + line rate for the MIPI D-PHY core in Mbps, the AXI4-stream received by + Xilinx MIPI DSI Tx IP core adds markers as per DSI protocol and the packet + thus framed is convered to serial data by MIPI D-PHY core. Please refer + Xilinx pg238 for more details. This value should be equal to the number + of lanes supported by the connected DSI panel. Panel has to support this + value or has to be programmed to the same value that DSI Tx controller is + configured to. + + - clocks: List of phandles to Video and 200Mhz DPHY clocks. + + - clock-names: Must contain "s_axis_aclk" and "dphy_clk_200M" in same order as + clocks listed in clocks property. + +Required simple_panel properties: + - compatible: Value should be one of the panel names in + Documentation/devicetree/bindings/display/panel/. e.g. "auo,b101uan01". + For available panel compatible strings, please refer to bindings in + Documentation/devicetree/bindings/display/panel/ + +Optional properties: + - xlnx,vpss: vpss phandle + This handle is required only when VPSS is connected to DSI as bridge. + - xlnx,dsi-cmd-mode: denotes command mode enable. + +Example: + +#include + mipi_dsi_tx_subsystem@80000000 { + compatible = "xlnx,dsi"; + reg = <0x0 0x80000000 0x0 0x10000>; + xlnx,dsi-num-lanes = <4>; + xlnx,dsi-data-type = ; + #address-cells = <1>; + #size-cells = <0>; + xlnx,vpss = <&v_proc_ss_0>; + clock-names = "dphy_clk_200M", "s_axis_aclk"; + clocks = <&misc_clk_0>, <&misc_clk_1>; + encoder_dsi_port: port@0 { + reg = <0>; + dsi_encoder: endpoint { + remote-endpoint = <&xyz_port>; + }; + }; + simple_panel: simple-panel@0 { + compatible = "auo,b101uan01"; + reg = <0>; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,mixer.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,mixer.txt @@ -0,0 +1,211 @@ +Device-Tree bindings for Xilinx Video Mixer IP core + +The IP core provides a flexible video processing block for alpha blending +and compositing multiple video and/or graphics layers. +Support for up to sixteen layers based on IP version, with an optional logo +layer, using a combination of video inputs from either frame buffer or +streaming video cores (through AXI4-Stream interfaces) is provided. +The Video Mixer always has one streaming input layer, known as master layer. + +Required properties: + - compatible: Must contain atleast one of + "xlnx,mixer-5.0" (MIXER 5.0 version) + "xlnx,mixer-4.0" (MIXER 4.0 version) + "xlnx,mixer-3.0" (MIXER 3.0 version) + - reg: Base address and size of the IP core. + - interrupts: Interrupt number. + - interrupts-parent: phandle for interrupt controller. + - reset-gpio: gpio to reset the mixer IP + - xlnx,enable-csc-coefficient-register: denotes colorimetry + coefficients can be programmed, valid for mixer 5.0 version only. + - xlnx,dma-addr-width: dma address width, valid values are 32 and 64 + - xlnx,bpc: bits per component for mixer + - xlnx,ppc: pixel per clock for mixer + - xlnx,num-layers: Total number of layers (excluding logo) + Value ranges from 1-9 for compatible string xlnx,mixer-3.0 and + Value ranges from 1-17 for comptaible string xlnx,mixer-4.0 and above + - layer_[x]: node for [x] layer + - xlnx,layer-id: layer identifier number + - xlnx,vformat: video format for layer. See list of supported formats below. + - xlnx,layer-max-width: max layer width, mandatory for master layer + for overlay layers if scaling is alowed then this is mandatory otherwise + not required for overlay layers. Valid range is 64 to 8192 + - xlnx,layer-max-height: max layer height, mandatory for master layer + Not required for overlay layers. Valid range is 64 to 4320 + - xlnx,layer-primary: denotes the primary layer, should be mentioned in node + of layer which is expected to be constructing the primary plane + +Optional properties: + - dmas: dma attach to layer, mandatory for master layer + for rest other layers its optional + - dma-names: Should be "dma0", for more details on DMA identifier string + refer Documentation/devicetree/bindings/dma/dma.txt + - xlnx,layer-streaming: denotes layer can be streaming, + mandatory for master layer. Streaming layers need external dma, where + as non streaming layers read directly from memory. + - xlnx,layer-alpha: denotes layer can do alpha compositing + - xlnx,layer-scale: denotes layer can be scale to 2x and 4x + - xlnx,logo-layer: denotes logo layer is enable + - logo: logo layer + - xlnx,bridge: phandle to bridge node. + This handle is required only when VTC is connected as bridge. + - memory-region: phandle to /reserved-memory node. + If memory is reserved for special use by mixer then this node + can be used to refer and use from this reserved memory region. + +Supported Formats: + Mixer IP Format Driver supported Format String + BGR888 "RG24" + RGB888 "BG24" + XBGR2101010 "XB30" + XRGB8888 "XR24" + RGBA8888 "RA24" + ABGR8888 "AB24" + ARGB8888 "AR24" + XBGR8888 "XB24" + YUYV "YUYV" + UYVY "UYVY" + AYUV "AYUV" + NV12 "NV12" + NV16 "NV16" + Y8 "GREY" + Y10 "Y10 " (Note: Space included) + XVUY2101010 "XV30" + VUY888 "VU24" + XVUY8888 "XV24" + XV15 "XV15" + XV20 "XV20" +Note : Format strings are case sensitive. + +Example: + v_mix_0: v_mix@80100000 { + compatible = "xlnx,mixer-3.0"; + interrupt-parent = <&gic>; + interrupts = <0 93 4>; + reg = <0x0 0x80100000 0x0 0x80000>; + + xlnx,dma-addr-width=<32>; + reset-gpios = <&gpio 1 1>; + + xlnx,bpc = <8>; + xlnx,ppc = <2>; + xlnx,num-layers = <8>; + xlnx,logo-layer; + xlnx,bridge = <&v_tc_0>; + + mixer_port: mixer_port@0 { + reg = <0>; + mixer_crtc: endpoint { + remote-endpoint = <&sdi_encoder>; + }; + }; + xv_mix_master: layer_0 { + xlnx,layer-id = <0>; + xlnx,vformat = "YUYV"; + xlnx,layer-max-width = <4096>; + xlnx,layer-height = <2160>; + dmas = <&axi_vdma_0 0>; + dma-names = "dma0"; + xlnx,layer-streaming; + xlnx,layer-primary; + }; + xv_mix_overlay_1: layer_1 { + xlnx,layer-id = <1>; + xlnx,vformat = "NV16"; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_overlay_2: layer_2 { + xlnx,layer-id = <2>; + xlnx,vformat = "YUYV"; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_overlay_3: layer_3 { + xlnx,layer-id = <3>; + xlnx,vformat = "AYUV"; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_overlay_4: layer_4 { + xlnx,layer-id = <4>; + xlnx,vformat = "GREY"; + dmas = <&scaler_v_frmbuf_rd_0 0>; + dma-names = "dma0"; + xlnx,layer-streaming; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_overlay_5: layer_5 { + xlnx,layer-id = <5>; + xlnx,vformat = "AB24"; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_overlay_6: layer_6 { + xlnx,layer-id = <6>; + xlnx,vformat = "XB24"; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_overlay_7: layer_7 { + xlnx,layer-id = <7>; + xlnx,vformat = "BG24"; + xlnx,layer-alpha; + xlnx,layer-scale; + xlnx,layer-max-width=<1920>; + }; + xv_mix_logo: logo { + xlnx,layer-id = <8>; + xlnx,logo-height = <64>; + xlnx,logo-width = <64>; + }; + }; +Example using reserved memory: +Reserving from 32bit Shared CMA pool of 512MiB using System RAM: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/ { + reserved-memory { + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + psmem_multimedia: multimedia_cma_mem_region { + compatible = "shared-dma-pool"; + reg = <0x00 0x40000000 0x00 0x20000000>; + reusable; + }; + }; +}; +... + v_mix_0: v_mix@80100000 { + /* ... */ + memory-region = <&psmem_multimedia>; + }; + +Reserving from 64bit Shared DMA pool of 1792 MiB using external PL based +DDR memory: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/ { + reserved-memory { + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + plmem_multimedia: multimedia_dma_mem_region { + compatible = "shared-dma-pool"; + no-map; + reg = <0x48 0x0 0x0 0x70000000>; + }; + }; + +}; +... + v_mix_0: v_mix@80100000 { + /* ... */ + memory-region = <&plmem_multimedia>; + } --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,pl-disp.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,pl-disp.txt @@ -0,0 +1,41 @@ +Xilinx PL Display driver +------------------------ + +Pl_Display is a logical device to provide completeness to xilinx display +pipeline. This is a software driver for providing drm components crtc +and plane for various IPs using xilinx display pipelines. + +A linear pipeline with multiple blocks: +DMA --> PL_Display --> SDI + +Required properties: + +- compatible: Must be "xlnx,pl-disp" +- dmas: dma attach to pipeline +- dma-names: names for dma +- xlnx,vformat: video format for layer +- port: Logical block can be used / connected independently with + external device. In the display controller port nodes, topology + for entire pipeline should be described using the DT bindings defined in + Documentation/devicetree/bindings/graph.txt. +- reg: Base address and size of device + +Optional properties: + - xlnx,bridge: bridge phandle + This handle is required only when VTC is connected as bridge. + +Example: + + drm-pl-disp-drv { + compatible = "xlnx,pl-disp"; + dmas = <&axi_vdma_0 0>; + dma-names = "dma0"; + xlnx,vformat = "YUYV"; + xlnx,bridge = <&v_tc_0>; + pl_disp_port@0 { + reg = <0>; + endpoint { + remote-endpoint = <&sdi_port>; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,sdi-tx.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,sdi-tx.txt @@ -0,0 +1,63 @@ +Device-Tree bindings for Xilinx SDI Tx subsystem + +The IP core supports transmission of video data in SDI Tx protocol + +Required properties: + - compatible: Should be "xlnx,sdi-tx". + - interrupts: Interrupt number. + - interrupts-parent: phandle for interrupt controller. + - reg: Base address and size of the IP core. + - port: Logical block can be used / connected independently with + external device. In the display controller port nodes, topology + for entire pipeline should be described using the DT bindings defined in + Documentation/devicetree/bindings/graph.txt. + Minimum one port is required. At max, 2 ports are present. + The reg index for AXI4 stream port is 0 and for ancillary data is 1. + - clocks: List of phandles to AXI Lite, Video and SDI Tx Clock + - clock-names: Must contain "s_axi_aclk", "video_in_clk" and "sdi_tx_clk" + in same order as clocks listed in clocks property. + - phy-reset-gpio: Specifier for a gpio that asserts GT phy + +Optional properties: + - xlnx,vpss: vpss phandle + This handle is required only when VPSS is connected to SDI as bridge. + - xlnx,tx-insert-c-str-st352: Insert ST352 payload in Chroma stream. + - interrupt-names: Should be "sdi_tx_irq". This is only required when + multiple interrupts are connected in the hardware design. + - xlnx,qpll1enabled: boolean property present when the QPLL1 drives GT clock + absent with QPLL0 drives GT clock +- xlnx,picxo_enabled: boolean property present when PICXO is present in design + +Example: + + sdi_tx_subsystem@80000000 { + compatible = "xlnx,sdi-tx"; + reg = <0x0 0x80000000 0x0 0x10000>; + interrupt-parent = <&gic>; + interrupts = <0 90 4>; + interrupt-names = "sdi_tx_irq"; + #address-cells = <1>; + #size-cells = <0>; + xlnx,vpss = <&v_proc_ss_0>; + clock-names = "s_axi_aclk", "video_in_clk", "sdi_tx_clk"; + clocks = <&misc_clk_0>, <&misc_clk_1>, <&misc_clk_2>; + phy-reset-gpio = <&axi_gpio_0 0 0 0>; + xlnx,qpll1enabled; + ports { + #address-cells = <1>; + #size-cells = <0>; + encoder_sdi_port: port@0 { + reg = <0>; + sdi_encoder: endpoint { + remote-endpoint = <&pl_disp_crtc>; + }; + }; + + sdi_audio_port: port@1 { + reg = <1>; + sdi_audio_sink_port: endpoint { + remote-endpoint = <&sditx_audio_embed_src_port>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,v-hdmi-txss1.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,v-hdmi-txss1.yaml @@ -0,0 +1,204 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/xlnx/xlnx,v-hdmi-txss1.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx HDMI Transmitter Subsystem + +maintainers: + - Venkateshwar Rao Gannavarapu + +description: | + The Xilinx HDMI Tx Subsystem contains several subcores to implement + a HDMI Transmitter and outputs video data using HDMI protocol. + For more details refer to PG350 Xilinx HDMI-2.1 Tx Subsystem. + +properties: + compatible: + items: + - enum: + - xlnx,v-hdmi-txss1-1.1 + - xlnx,v-hdmi-txss1-1.2 + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 4 + + interrupt-names: + description: Only hdmitx interrupt is mandatory. Others are optional. + hdcp14 and hdcp14timer will be present when HDCP 1x + is selected. + hdcp22timer will be present when HDCP 2x is selected. + items: + - const: hdmitx + - const: hdcp14 + - const: hdcp14timer + - const: hdcp22timer + + clocks: + description: List of clock specifiers + items: + - description: AXI Lite CPU clock + - description: Link clock + - description: Video clock + - description: Fixed Rate Link clock + - description: AXI4-Stream Video clock + + clock-names: + items: + - const: s_axi_cpu_aclk + - const: link_clk + - const: video_clk + - const: frl_clk + - const: s_axis_video_aclk + + phys: + description: This denotes phandles for phy lanes registered + for HDMI protocol. HDMI always require 4 lanes + + phy-names: + items: + - const: hdmi-phy0 + - const: hdmi-phy1 + - const: hdmi-phy2 + - const: hdmi-phy3 + + xlnx,input-pixels-per-clock: + description: Configurable samples per clock. + Possible values are 4, 8. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [4, 8] + + xlnx,max-bits-per-component: + description: | + Max BPC value that IP configured with. For example if IP is configured + with 12 BPC means it supports (8, 10, 12) up to 12bpc. + Possible values are 8, 10, 12, 16. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [8, 10, 12, 16] + + xlnx,vid-interface: + description: Supported video interface. + Possible values are 0 for AXI4-Stream, + 1 for Native and 2 for Native-IDE interface. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1, 2] + + xlnx,max-frl-rate: + description: Maximum FRL Rate. + Possible values are 0 for TMDS mode, + 1 to 6 for FRL mode of operation. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1, 2, 3, 4, 5, 6] + + xlnx,include-hdcp-1-4: + type: boolean + $ref: /schemas/types.yaml#/definitions/flag + description: | + Present when HDCP1.4 is present in design. + + xlnx,include-hdcp-2-2: + type: boolean + $ref: /schemas/types.yaml#/definitions/flag + description: | + Present when HDCP2.2 is present in design. + + xlnx,hdcp1x-keymgmt: + description: + A phandle to a syscon device, used to access + hdcp1x keymgmt registers. + $ref: /schemas/types.yaml#/definitions/phandle + + ports: + type: object + + properties: + port@0: + type: object + description: | + Output / source port node, endpoint describing modules + connected the HDMI transmitter + + properties: + reg: + const: 0 + + endpoint: + type: object + + properties: + + remote-endpoint: true + + required: + - remote-endpoint + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - phys + - phy-names + - xlnx,input-pixels-per-clock + - xlnx,max-bits-per-component + - xlnx,vid-interface + - xlnx,max-frl-rate + - ports + +additionalProperties: false + +dependencies: + xlnx,include-hdcp-1-4: [ 'xlnx,hdcp1x-keymgmt' ] + xlnx,hdcp1x-keymgmt: [ 'xlnx,include-hdcp-1-4' ] + +examples: + - | + #include + + v_hdmi_txss1@80020000 { + compatible = "xlnx,v-hdmi-txss1-1.1"; + reg = <0x80020000 0x20000>; + interrupt-names = "hdmitx", "hdcp14", "hdcp14timer", + "hdcp22timer"; + interrupts = , , + , ; + clock-names = "s_axi_cpu_aclk", "link_clk", "video_clk", "frl_clk", "s_axis_video_aclk"; + clocks = <&zynqmp_clk 71>, <&misc_clk_1>, <&misc_clk_3>, <&misc_clk_4>, <&misc_clk_5>; + xlnx,input-pixels-per-clock = <4>; + xlnx,max-bits-per-component = <0x8>; + xlnx,vid-interface = <0>; + xlnx,max-frl-rate = <0x6>; + xlnx,include-hdcp-1-4; + xlnx,include-hdcp-2-2; + xlnx,hdcp1x-keymgmt = <&hdcp_keymngmt_blk_0>; + phy-names = "hdmi-phy0", "hdmi-phy1", "hdmi-phy2", "hdmi-phy3"; + phys = <&hdmiphy_lane0 0 1 1 1>, <&hdmiphy_lane1 0 1 1 1>, + <&hdmiphy_lane2 0 1 1 1>, <&hdmiphy_lane3 0 1 1 1>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + hdmi_encoder: endpoint { + remote-endpoint = <&dmaengine_crtc>; + }; + }; + }; + }; + + hdcp_keymngmt_blk_0: hdcp_keymngmt_blk@80030000 { + compatible = "xlnx,hdcp-keymngmt-blk-1.0", "syscon"; + reg = <0x80030000 0x10000>; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,vpss-csc.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,vpss-csc.txt @@ -0,0 +1,35 @@ +Xllinx VPSS Color Space Converter +----------------------------------------- +The Xilinx VPSS Color Space Converter is a Video IP that supports +color space conversion from RGB to YUV 444/422/420 and vice versa. + +Required properties: + +- compatible: Must be "xlnx,vpss-csc". + +- reg: Physical base address and length of registers set for the device. + +- xlnx,video-width: This property qualifies the video format with sample + width expressed as a number of bits per pixel component. Supported video + width values are 8/10/12/16. + +-reset-gpios: GPIO specifier to assert/de-assert the reset line. + +- clocks: phandle to IP clock. + +- xlnx,max-width: Maximum number of pixels in a line. + Valid range from 64 to 8192. + +- xlnx,max-height: Maximum number of lines in a frame. + Valid range from 64 to 4320. + +Example: + csc@a0040000 { + compatible = "xlnx,vpss-csc"; + reg = <0x0 0xa0040000 0x0 0x10000>; + reset-gpios = <&gpio 0x0 GPIO_ACTIVE_LOW>; + xlnx,video-width = <8>; + clocks = <&misc_clk_0>; + xlnx,max-width = <3840>; + xlnx,max-height = <2160>; + } --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,vpss-scaler.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,vpss-scaler.txt @@ -0,0 +1,50 @@ +Xilinx VPSS Scaler +------------------ +The Xilinx VPSS Scaler is a Video IP that supports up scaling, +down scaling and no scaling functionailty. This supports custom +resolution values between 0 to 4096. + +Required properties: + +- compatible: Must be "xlnx,vpss-scaler-2.2" or "xlnx,vpss-scaler". + +- reg: Physical base address and length of registers set for the device. + +- xlnx,num-hori-taps: The number of horizontal taps for scaling filter + supported tap values are 2/4/6/8/10/12. + +- xlnx,num-vert-taps: The number of vertical taps for scaling filter + supported tap values are 2/4/6/8/10/12. + + A value of 2 represents bilinear filters. A value of 4 represents bicubic. + Values 6, 8, 10, 12 represent polyphase filters. + +- xlnx,pix-per-clk : The pixels per clock property of the IP. + supported values are 1 and 2. + +- reset-gpios: GPIO specifier to assert/de-assert the reset line. + +- clocks: List of phandles to AXI Lite and Video clock + +- clock-names: Must contain "aclk_ctrl" and "aclk_axis" in same order as clocks + listed in clocks property. + +- xlnx,max-width: Maximum number of pixels in a line. + Valid range from 64 to 8192. + +- xlnx,max-height: Maximum number of lines in a frame. + Valid range from 64 to 4320. + +Example: + scaler@a0040000 { + compatible = "xlnx,vpss-scaler"; + reg = <0x0 0xa0000000 0x0 0x40000>; + reset-gpios = <&gpio 0x0 GPIO_ACTIVE_LOW>; + xlnx,num-hori-taps = <8>; + xlnx,num-vert-taps = <8>; + xlnx,pix-per-clk = <2>; + clock-names = "aclk_ctrl", "aclk_axis"; + clocks = <&misc_clk_0>, <&misc_clk_1>; + xlnx,max-width = <3840>; + xlnx,max-height = <2160>; + } --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,vtc.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,vtc.txt @@ -0,0 +1,32 @@ +Device-Tree bindings for Xilinx Video Timing Controller(VTC) + +Xilinx VTC is a general purpose video timing generator and detector. +The input side of this core automatically detects horizontal and +vertical synchronization, pulses, polarity, blanking timing and active pixels. +While on the output, it generates the horizontal and vertical blanking and +synchronization pulses used with a standard video system including support +for programmable pulse polarity. + +The core is commonly used with Video in to AXI4-Stream core to detect the +format and timing of incoming video data or with AXI4-Stream to Video out core +to generate outgoing video timing for downstream sinks like a video monitor. + +For details please refer to +https://www.xilinx.com/support/documentation/ip_documentation/v_tc/v6_1/pg016_v_tc.pdf + +Required properties: + - compatible: value should be "xlnx,bridge-v-tc-6.1" + - reg: base address and size of the VTC IP + - xlnx,pixels-per-clock: Pixels per clock of the stream. Can be 1, 2 or 4. + - clocks: List of phandles for AXI Lite and Video Clock + - clock-names: Must contain "s_axi_aclk" and "clk" in same order as clocks listed + in clocks property. + +Example: + v_tc_0: v_tc@80030000 { + compatible = "xlnx,bridge-v-tc-6.1"; + reg = <0x0 0x80030000 0x0 0x10000>; + xlnx,pixels-per-clock = <2>; + clock-names = "s_axi_aclk", "clk"; + clocks = <&misc_clk_0>, <&misc_clk_1>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.txt @@ -0,0 +1,82 @@ +Xilinx ZynqMP DisplayPort subsystem +----------------------------------- + +Required properties: + +- compatible: Must be "xlnx,zynqmp-dpsub-1.7". + +- reg: Physical base address and length of the registers set for the device. +- reg-names: Must be "dp", "blend", "av_buf", and "aud" to map logical register + partitions. + +- interrupts: Interrupt number. +- interrupts-parent: phandle for interrupt controller. + +- clocks: phandles for axi, audio, non-live video, and live video clocks. + axi clock is required. Audio clock is optional. If not present, audio will + be disabled. One of non-live or live video clock should be present. +- clock-names: The identification strings are required. "aclk" for axi clock. + "dp_aud_clk" for audio clock. "dp_vtc_pixel_clk_in" for non-live video clock. + "dp_live_video_in_clk" for live video clock (clock from programmable logic). + +- phys: phandles for phy specifier. The number of lanes is configurable + between 1 and 2. The number of phandles should be 1 or 2. +- phy-names: The identifier strings. "dp-phy" followed by index, 0 or 1. + For single lane, only "dp-phy0" is required. For dual lane, both "dp-phy0" + and "dp-phy1" are required where "dp-phy0" is the primary lane. + +- power-domains: phandle for the corresponding power domain + +- vid-layer, gfx-layer: Required to represent available layers + +Required layer properties + +- dmas: phandles for DMA channels as defined in + Documentation/devicetree/bindings/dma/dma.txt. +- dma-names: The identifier strings are required. "gfx0" for graphics layer + dma channel. "vid" followed by index (0 - 2) for video layer dma channels. + +Optional child node + +- The driver populates any child device node in this node. This can be used, + for example, to populate the sound device from the DisplayPort subsystem + driver. + +Example: + zynqmp-display-subsystem@fd4a0000 { + compatible = "xlnx,zynqmp-dpsub-1.7"; + reg = <0x0 0xfd4a0000 0x0 0x1000>, + <0x0 0xfd4aa000 0x0 0x1000>, + <0x0 0xfd4ab000 0x0 0x1000>, + <0x0 0xfd4ac000 0x0 0x1000>; + reg-names = "dp", "blend", "av_buf", "aud"; + interrupts = <0 119 4>; + interrupt-parent = <&gic>; + + clock-names = "dp_apb_clk", "dp_aud_clk", "dp_live_video_in_clk"; + clocks = <&dp_aclk>, <&clkc 17>, <&si570_1>; + + phys = <&lane1>, <&lane0>; + phy-names = "dp-phy0", "dp-phy1"; + + power-domains = <&pd_dp>; + + vid-layer { + dma-names = "vid0", "vid1", "vid2"; + dmas = <&xlnx_dpdma 0>, + <&xlnx_dpdma 1>, + <&xlnx_dpdma 2>; + }; + + gfx-layer { + dma-names = "gfx0"; + dmas = <&xlnx_dpdma 3>; + }; + + dma-names = "vid0", "vid1", "vid2", "gfx0"; + dmas = <&xlnx_dpdma 0>, + <&xlnx_dpdma 1>, + <&xlnx_dpdma 2>, + <&xlnx_dpdma 3>; + }; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/display/xlnx/xlnx,zynqmp-dpsub.yaml @@ -49,13 +49,18 @@ const: xlnx,zynqmp-dpsub-1.7 reg: - maxItems: 4 + maxItems: 3 reg-names: items: - const: dp - const: blend - const: av_buf - - const: aud + + xlnx,dpaud-reg: + description: + A phandle to a syscon device, used to access + dp audio cfg registers. + $ref: /schemas/types.yaml#/definitions/phandle interrupts: maxItems: 1 @@ -160,6 +165,7 @@ - compatible - reg - reg-names + - xlnx,dpaud-reg - interrupts - clocks - clock-names @@ -182,9 +188,9 @@ compatible = "xlnx,zynqmp-dpsub-1.7"; reg = <0xfd4a0000 0x1000>, <0xfd4aa000 0x1000>, - <0xfd4ab000 0x1000>, - <0xfd4ac000 0x1000>; - reg-names = "dp", "blend", "av_buf", "aud"; + <0xfd4ab000 0x1000>; + reg-names = "dp", "blend", "av_buf"; + xlnx,dpaud-reg = <&dp_aud>; interrupts = <0 119 4>; interrupt-parent = <&gic>; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/dma/fsl,edma.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/dma/fsl,edma.yaml @@ -47,8 +47,8 @@ - 3 dma-channels: - minItems: 1 - maxItems: 64 + minimum: 1 + maximum: 64 clocks: minItems: 1 --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/dma/xilinx/xilinx_frmbuf.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/dma/xilinx/xilinx_frmbuf.txt @@ -0,0 +1,128 @@ +The Xilinx framebuffer DMA engine supports two soft IP blocks: one IP +block is used for reading video frame data from memory (FB Read) to the device +and the other IP block is used for writing video frame data from the device +to memory (FB Write). Both the FB Read/Write IP blocks are aware of the +format of the data being written to or read from memory including RGB and +YUV in packed, planar, and semi-planar formats. Because the FB Read/Write +is format aware, only one buffer pointer is needed by the IP blocks even +when planar or semi-planar format are used. + +FB Read Required propertie(s): +- compatible : Should be "xlnx,axi-frmbuf-rd-v2.1" or + "xlnx,axi-frmbuf-rd-v2.2". Older string + "xlnx,axi-frmbuf-rd-v2" is now deprecated. + +Note: Compatible string "xlnx,axi-frmbuf-rd" and the hardware it +represented is no longer supported. + +FB Write Required propertie(s): +- compatible : Should be "xlnx,axi-frmbuf-wr-v2.1" or + "xlnx,axi-frmbuf-wr-v2.2". Older string + "xlnx,axi-frmbuf-wr-v2" is now deprecated. + +Note: Compatible string "xlnx,axi-frmbuf-wr" and the hardware it +represented is no longer supported. + +Required Properties Common to both FB Read and FB Write: +- #dma-cells : should be 1 +- interrupt-parent : Interrupt controller the interrupt is routed through +- interrupts : Should contain DMA channel interrupt +- reset-gpios : Should contain GPIO reset phandle +- reg : Memory map for module access +- xlnx,dma-addr-width : Size of dma address pointer in IP (either 32 or 64) +- xlnx,vid-formats : A list of strings indicating what video memory + formats the IP has been configured to support. + See VIDEO FORMATS table below and examples. + +Required Properties Common to both FB Read and FB Write for v2.1: +- xlnx,pixels-per-clock : Pixels per clock set in IP (1, 2, 4 or 8) +- clocks: Reference to the AXI Streaming clock feeding the AP_CLK +- clock-names: Must have "ap_clk" +- xlnx,max-height : Maximum number of lines. + Valid range from 64 to 8640. +- xlnx,max-width : Maximum number of pixels in a line. + Valid range from 64 to 15360. + +Optional Properties Common to both FB Read and FB Write for v2.1: +- xlnx,dma-align : DMA alignment required in bytes. + If absent then dma alignment is calculated as + pixels per clock * 8. + If present it should be power of 2 and at least + pixels per clock * 8. + Minimum is 8, 16, 32 when pixels-per-clock is + 1, 2 or 4. +- xlnx,fid : Field ID enabled for interlaced video support. + Can be absent for progressive video. + +VIDEO FORMATS +The following table describes the legal string values to be used for +the xlnx,vid-formats property. To the left is the string value and the +two columns to the right describe how this is mapped to an equivalent V4L2 +and DRM fourcc code---respectively---by the driver. + +IP FORMAT DTS String V4L2 Fourcc DRM Fourcc +-------------|----------------|----------------------|--------------------- +RGB8 bgr888 V4L2_PIX_FMT_RGB24 DRM_FORMAT_BGR888 +BGR8 rgb888 V4L2_PIX_FMT_BGR24 DRM_FORMAT_RGB888 +RGBX8 xbgr8888 V4L2_PIX_FMT_BGRX32 DRM_FORMAT_XBGR8888 +RGBA8 abgr8888 DRM_FORMAT_ABGR8888 +BGRA8 argb8888 DRM_FORMAT_ARGB8888 +BGRX8 xrgb8888 V4L2_PIX_FMT_XBGR32 DRM_FORMAT_XRGB8888 +RGBX10 xbgr2101010 V4L2_PIX_FMT_XBGR30 DRM_FORMAT_XBGR2101010 +RGBX12 xbgr2121212 V4L2_PIX_FMT_XBGR40 +RGBX16 rgb16 V4L2_PIX_FMT_BGR40 +YUV8 vuy888 V4L2_PIX_FMT_VUY24 DRM_FORMAT_VUY888 +YUVX8 xvuy8888 V4L2_PIX_FMT_XVUY32 DRM_FORMAT_XVUY8888 +Y_U_V8 y_u_v8 V4L2_PIX_FMT_YUV444P DRM_FORMAT_YUV444 +Y_U_V8 y_u_v8 V4L2_PIX_FMT_YUV444M DRM_FORMAT_YUV444 +Y_U_V10 y_u_v10 V4L2_PIX_FMT_X403 DRM_FORMAT_X403 +YUYV8 yuyv V4L2_PIX_FMT_YUYV DRM_FORMAT_YUYV +UYVY8 uyvy V4L2_PIX_FMT_UYVY DRM_FORMAT_UYVY +YUVA8 avuy8888 DRM_FORMAT_AVUY +YUVX10 yuvx2101010 V4L2_PIX_FMT_XVUY10 DRM_FORMAT_XVUY2101010 +Y8 y8 V4L2_PIX_FMT_GREY DRM_FORMAT_Y8 +Y10 y10 V4L2_PIX_FMT_XY10 DRM_FORMAT_Y10 +Y_UV8 nv16 V4L2_PIX_FMT_NV16 DRM_FORMAT_NV16 +Y_UV8 nv16 V4L2_PIX_FMT_NV16M DRM_FORMAT_NV16 +Y_UV8_420 nv12 V4L2_PIX_FMT_NV12 DRM_FORMAT_NV12 +Y_UV8_420 nv12 V4L2_PIX_FMT_NV12M DRM_FORMAT_NV12 +Y_UV10 xv20 V4L2_PIX_FMT_XV20M DRM_FORMAT_XV20 +Y_UV10 xv20 V4L2_PIX_FMT_XV20 +Y_UV10_420 xv15 V4L2_PIX_FMT_XV15M DRM_FORMAT_XV15 +Y_UV10_420 xv15 V4L2_PIX_FMT_XV20 + +Examples: + +FB Read Example: +++++++++ +v_frmbuf_rd_0: v_frmbuf_rd@80000000 { + #dma-cells = <1>; + compatible = "xlnx,axi-frmbuf-rd-v2.1"; + interrupt-parent = <&gic>; + interrupts = <0 92 4>; + reset-gpios = <&gpio 80 1>; + reg = <0x0 0x80000000 0x0 0x10000>; + xlnx,dma-addr-width = <32>; + xlnx,vid-formats = "bgr888","xbgr8888"; + xlnx,pixels-per-clock = <1>; + xlnx,dma-align = <8>; + clocks = <&vid_stream_clk>; + clock-names = "ap_clk" +}; + +FB Write Example: +++++++++ +v_frmbuf_wr_0: v_frmbuf_wr@80000000 { + #dma-cells = <1>; + compatible = "xlnx,axi-frmbuf-wr-v2.1"; + interrupt-parent = <&gic>; + interrupts = <0 92 4>; + reset-gpios = <&gpio 80 1>; + reg = <0x0 0x80000000 0x0 0x10000>; + xlnx,dma-addr-width = <64>; + xlnx,vid-formats = "bgr888","yuyv","nv16","nv12"; + xlnx,pixels-per-clock = <2>; + xlnx,dma-align = <16>; + clocks = <&vid_stream_clk>; + clock-names = "ap_clk" +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/dma/xilinx/xlnx,axi-dma-test.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/dma/xilinx/xlnx,axi-dma-test.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/xilinx/xlnx,axi-dma-test.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx AXI DMA Test client + +maintainers: + - Radhey Shyam Pandey + - Harini Katakam + +properties: + compatible: + const: xlnx,axi-dma-test-1.00.a + + dmas: + description: + A list of <[DMA device phandle] [Channel ID]> pairs, + where Channel ID is '0' for write/tx and '1' for read/rx + channel. + maxItems: 2 + + dma-names: + items: + - const: axidma0 + - const: axidma1 + +required: + - compatible + - dmas + - dma-names + +unevaluatedProperties: false + +examples: + - | + dmatest_0: dmatest { + compatible ="xlnx,axi-dma-test-1.00.a"; + dmas = <&axi_dma_0 0 &axi_dma_0 1>; + dma-names = "axidma0", "axidma1"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/dma/xilinx/xlnx,axi-vdma-test.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/dma/xilinx/xlnx,axi-vdma-test.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/xilinx/xlnx,axi-vdma-test.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Video DMA Test client + +maintainers: + - Radhey Shyam Pandey + - Harini Katakam + +properties: + compatible: + const: xlnx,axi-vdma-test-1.00.a + + dmas: + description: + A list of <[DMA device phandle] [Channel ID]> pairs, + where Channel ID is '0' for write/tx and '1' for read/rx + channel. + maxItems: 2 + + dma-names: + items: + - const: vdma0 + - const: vdma1 + + xlnx,num-fstores: + description: + Should be the number of framebuffers as configured in + VDMA device node. + $ref: /schemas/types.yaml#/definitions/uint32 + +required: + - compatible + - dmas + - dma-names + - xlnx,num-fstores + +unevaluatedProperties: false + +examples: + - | + vdmatest_0: vdmatest { + compatible ="xlnx,axi-vdma-test-1.00.a"; + dmas = <&axi_vdma_0 0 &axi_vdma_0 1>; + dma-names = "vdma0", "vdma1"; + xlnx,num-fstores = <0x8>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml @@ -24,7 +24,9 @@ const: 1 compatible: - const: xlnx,zynqmp-dma-1.0 + enum: + - amd,versal2-dma-1.0 + - xlnx,zynqmp-dma-1.0 reg: description: memory map for gdma/adma module access --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/edac/xlnx,versal-xilsem-edac.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/edac/xlnx,versal-xilsem-edac.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/edac/xlnx,versal-xilsem-edac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Versal Xilsem EDAC driver + +maintainers: + - Rama Devi Veggalam + +description: | + Xilinx Versal Soft Error Mitigation (XilSEM) is part of the + Platform Loader and Manager (PLM) which is loaded into and runs on the + Platform Management Controller (PMC). XilSEM is responsible for detecting + and optionally correcting soft errors in Configuration Memory of Versal. + Whenever an error is detected, be it correctable or uncorrectable, XilSEM + notifies the errors to user application. + This driver is responsible for handling error events received from XilSEM + on PLM. + +properties: + compatible: + items: + - enum: + - xlnx,versal-xilsem-edac + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + edac@f2014050 { + compatible = "xlnx,versal-xilsem-edac"; + reg = <0xf2014050 0xc4>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/eeprom/at24.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/eeprom/at24.yaml @@ -69,14 +69,10 @@ - items: pattern: c32$ - items: - pattern: c32d-wl$ - - items: pattern: cs32$ - items: pattern: c64$ - items: - pattern: c64d-wl$ - - items: pattern: cs64$ - items: pattern: c128$ @@ -136,6 +132,7 @@ - renesas,r1ex24128 - samsung,s524ad0xd1 - const: atmel,24c128 + - pattern: '^atmel,24c(32|64)d-wl$' # Actual vendor is st label: description: Descriptive name of the EEPROM. --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.yaml @@ -26,6 +26,12 @@ - description: For implementations complying for Versal. const: xlnx,versal-firmware + - description: For implementations complying for Versal NET. + items: + - enum: + - xlnx,versal-net-firmware + - const: xlnx,versal-firmware + method: description: | The method of calling the PM-API firmware layer. @@ -41,7 +47,44 @@ "#power-domain-cells": const: 1 - versal_fpga: + gpio: + $ref: /schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml# + description: The gpio node describes connect to PS_MODE pins via firmware + interface. + type: object + + soc-nvmem: + $ref: /schemas/nvmem/xlnx,zynqmp-nvmem.yaml# + description: The ZynqMP MPSoC provides access to the hardware related data + like SOC revision, IDCODE and specific purpose efuses. + type: object + + pcap: + $ref: /schemas/fpga/xlnx,zynqmp-pcap-fpga.yaml + description: The ZynqMP SoC uses the PCAP (Processor Configuration Port) to + configure the Programmable Logic (PL). The configuration uses the + firmware interface. + type: object + + pinctrl: + $ref: /schemas/pinctrl/xlnx,zynqmp-pinctrl.yaml# + description: The pinctrl node provides access to pinconfig and pincontrol + functionality available in firmware. + type: object + + power-management: + $ref: /schemas/power/reset/xlnx,zynqmp-power.yaml# + description: The zynqmp-power node describes the power management + configurations. It will control remote suspend/shutdown interfaces. + type: object + + reset-controller: + $ref: /schemas/reset/xlnx,zynqmp-reset.yaml# + description: The reset-controller node describes connection to the reset + functionality via firmware interface. + type: object + + versal-fpga: $ref: /schemas/fpga/xlnx,versal-fpga.yaml# description: Compatible of the FPGA device. type: object @@ -52,6 +95,7 @@ used to encrypt or decrypt the data with provided key and initialization vector. type: object + deprecated: true clock-controller: $ref: /schemas/clock/xlnx,versal-clk.yaml# @@ -73,7 +117,38 @@ firmware { zynqmp_firmware: zynqmp-firmware { #power-domain-cells = <1>; + soc-nvmem { + compatible = "xlnx,zynqmp-nvmem-fw"; + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + soc_revision: soc-revision@0 { + reg = <0x0 0x4>; + }; + }; + }; + gpio { + compatible = "xlnx,zynqmp-gpio-modepin"; + gpio-controller; + #gpio-cells = <2>; + }; + pcap { + compatible = "xlnx,zynqmp-pcap-fpga"; }; + pinctrl { + compatible = "xlnx,zynqmp-pinctrl"; + }; + power-management { + compatible = "xlnx,zynqmp-power"; + interrupts = <0 35 4>; + }; + reset-controller { + compatible = "xlnx,zynqmp-reset"; + #reset-cells = <1>; + }; + }; }; sata { @@ -84,7 +159,7 @@ compatible = "xlnx,versal-firmware"; method = "smc"; - versal_fpga: versal_fpga { + versal_fpga: versal-fpga { compatible = "xlnx,versal-fpga"; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/fpga/fpga-region.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/fpga/fpga-region.yaml @@ -0,0 +1,358 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/fpga/fpga-region.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: FPGA Region + +maintainers: + - Michal Simek + +description: | + CONTENTS + - Introduction + - Terminology + - Sequence + - FPGA Region + - Supported Use Models + - Constraints + + + Introduction + ============ + + FPGA Regions represent FPGA's and partial reconfiguration regions of FPGA's in + the Device Tree. FPGA Regions provide a way to program FPGAs under device tree + control. + + The documentation hits some of the high points of FPGA usage and + attempts to include terminology used by both major FPGA manufacturers. This + document isn't a replacement for any manufacturers specifications for FPGA + usage. + + + Terminology + =========== + + Full Reconfiguration + * The entire FPGA is programmed. + + Partial Reconfiguration (PR) + * A section of an FPGA is reprogrammed while the rest of the FPGA is not + affected. + * Not all FPGA's support PR. + + Partial Reconfiguration Region (PRR) + * Also called a "reconfigurable partition" + * A PRR is a specific section of an FPGA reserved for reconfiguration. + * A base (or static) FPGA image may create a set of PRR's that later may + be independently reprogrammed many times. + * The size and specific location of each PRR is fixed. + * The connections at the edge of each PRR are fixed. The image that is loaded + into a PRR must fit and must use a subset of the region's connections. + * The busses within the FPGA are split such that each region gets its own + branch that may be gated independently. + + Persona + * Also called a "partial bit stream" + * An FPGA image that is designed to be loaded into a PRR. There may be + any number of personas designed to fit into a PRR, but only one at a time + may be loaded. + * A persona may create more regions. + + FPGA Bridge + * FPGA Bridges gate bus signals between a host and FPGA. + * FPGA Bridges should be disabled while the FPGA is being programmed to + prevent spurious signals on the cpu bus and to the soft logic. + * FPGA bridges may be actual hardware or soft logic on an FPGA. + * During Full Reconfiguration, hardware bridges between the host and FPGA + will be disabled. + * During Partial Reconfiguration of a specific region, that region's bridge + will be used to gate the busses. Traffic to other regions is not affected. + * In some implementations, the FPGA Manager transparently handles gating the + buses, eliminating the need to show the hardware FPGA bridges in the + device tree. + * An FPGA image may create a set of reprogrammable regions, each having its + own bridge and its own split of the busses in the FPGA. + + FPGA Manager + * An FPGA Manager is a hardware block that programs an FPGA under the control + of a host processor. + + Base Image + * Also called the "static image" + * An FPGA image that is designed to do full reconfiguration of the FPGA. + * A base image may set up a set of partial reconfiguration regions that may + later be reprogrammed. + + ---------------- ---------------------------------- + | Host CPU | | FPGA | + | | | | + | ----| | ----------- -------- | + | | H | | |==>| Bridge0 |<==>| PRR0 | | + | | W | | | ----------- -------- | + | | | | | | + | | B |<=====>|<==| ----------- -------- | + | | R | | |==>| Bridge1 |<==>| PRR1 | | + | | I | | | ----------- -------- | + | | D | | | | + | | G | | | ----------- -------- | + | | E | | |==>| Bridge2 |<==>| PRR2 | | + | ----| | ----------- -------- | + | | | | + ---------------- ---------------------------------- + + Figure 1: An FPGA set up with a base image that created three regions. Each + region (PRR0-2) gets its own split of the busses that is independently gated by + a soft logic bridge (Bridge0-2) in the FPGA. The contents of each PRR can be + reprogrammed independently while the rest of the system continues to function. + + + Sequence + ======== + + When a DT overlay that targets an FPGA Region is applied, the FPGA Region will + do the following: + + 1. Disable appropriate FPGA bridges. + 2. Program the FPGA using the FPGA manager. + 3. Enable the FPGA bridges. + 4. The Device Tree overlay is accepted into the live tree. + 5. Child devices are populated. + + When the overlay is removed, the child nodes will be removed and the FPGA Region + will disable the bridges. + + + FPGA Region + =========== + + FPGA Regions represent FPGA's and FPGA PR regions in the device tree. An FPGA + Region brings together the elements needed to program on a running system and + add the child devices: + + * FPGA Manager + * FPGA Bridges + * image-specific information needed to the programming. + * child nodes + + The intended use is that a Device Tree overlay (DTO) can be used to reprogram an + FPGA while an operating system is running. + + An FPGA Region that exists in the live Device Tree reflects the current state. + If the live tree shows a "firmware-name" property or child nodes under an FPGA + Region, the FPGA already has been programmed. A DTO that targets an FPGA Region + and adds the "firmware-name" property is taken as a request to reprogram the + FPGA. After reprogramming is successful, the overlay is accepted into the live + tree. + + The base FPGA Region in the device tree represents the FPGA and supports full + reconfiguration. It must include a phandle to an FPGA Manager. The base + FPGA region will be the child of one of the hardware bridges (the bridge that + allows register access) between the cpu and the FPGA. If there are more than + one bridge to control during FPGA programming, the region will also contain a + list of phandles to the additional hardware FPGA Bridges. + + For partial reconfiguration (PR), each PR region will have an FPGA Region. + These FPGA regions are children of FPGA bridges which are then children of the + base FPGA region. The "Full Reconfiguration to add PRR's" example below shows + this. + + If an FPGA Region does not specify an FPGA Manager, it will inherit the FPGA + Manager specified by its ancestor FPGA Region. This supports both the case + where the same FPGA Manager is used for all of an FPGA as well the case where + a different FPGA Manager is used for each region. + + FPGA Regions do not inherit their ancestor FPGA regions' bridges. This prevents + shutting down bridges that are upstream from the other active regions while one + region is getting reconfigured (see Figure 1 above). During PR, the FPGA's + hardware bridges remain enabled. The PR regions' bridges will be FPGA bridges + within the static image of the FPGA. + + + Supported Use Models + ==================== + + In all cases the live DT must have the FPGA Manager, FPGA Bridges (if any), and + a FPGA Region. The target of the Device Tree Overlay is the FPGA Region. Some + uses are specific to an FPGA device. + + * No FPGA Bridges + In this case, the FPGA Manager which programs the FPGA also handles the + bridges behind the scenes. No FPGA Bridge devices are needed for full + reconfiguration. + + * Full reconfiguration with hardware bridges + In this case, there are hardware bridges between the processor and FPGA that + need to be controlled during full reconfiguration. Before the overlay is + applied, the live DT must include the FPGA Manager, FPGA Bridges, and a + FPGA Region. The FPGA Region is the child of the bridge that allows + register access to the FPGA. Additional bridges may be listed in a + fpga-bridges property in the FPGA region or in the device tree overlay. + + * Partial reconfiguration with bridges in the FPGA + In this case, the FPGA will have one or more PRR's that may be programmed + separately while the rest of the FPGA can remain active. To manage this, + bridges need to exist in the FPGA that can gate the buses going to each FPGA + region while the buses are enabled for other sections. Before any partial + reconfiguration can be done, a base FPGA image must be loaded which includes + PRR's with FPGA bridges. The device tree should have an FPGA region for each + PRR. + + Constraints + =========== + + It is beyond the scope of this document to fully describe all the FPGA design + constraints required to make partial reconfiguration work[1] [2] [3], but a few + deserve quick mention. + + A persona must have boundary connections that line up with those of the partition + or region it is designed to go into. + + During programming, transactions through those connections must be stopped and + the connections must be held at a fixed logic level. This can be achieved by + FPGA Bridges that exist on the FPGA fabric prior to the partial reconfiguration. + + -- + [1] www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_partrecon.pdf + [2] tspace.library.utoronto.ca/bitstream/1807/67932/1/Byma_Stuart_A_201411_MAS_thesis.pdf + [3] https://www.xilinx.com/support/documentation/sw_manuals/xilinx14_1/ug702.pdf + +properties: + $nodename: + pattern: "^fpga-region(@.*|-([0-9]|[1-9][0-9]+))?$" + + compatible: + const: fpga-region + + reg: + maxItems: 1 + + ranges: true + "#address-cells": true + "#size-cells": true + + config-complete-timeout-us: + description: + The maximum time in microseconds time for the FPGA to go to operating + mode after the region has been programmed. + + encrypted-fpga-config: + type: boolean + description: + Set if the bitstream is encrypted. + + external-fpga-config: + type: boolean + description: + Set if the FPGA has already been configured prior to OS boot up. + + firmware-name: + maxItems: 1 + description: + Should contain the name of an FPGA image file located on the firmware + search path. If this property shows up in a live device tree it indicates + that the FPGA has already been programmed with this image. + If this property is in an overlay targeting an FPGA region, it is + a request to program the FPGA with that image. + + fpga-bridges: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: + Should contain a list of phandles to FPGA Bridges that must be + controlled during FPGA programming along with the parent FPGA bridge. + This property is optional if the FPGA Manager handles the bridges. + If the fpga-region is the child of an fpga-bridge, the list should not + contain the parent bridge. + + fpga-mgr: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Should contain a phandle to an FPGA Manager. Child FPGA Regions + inherit this property from their ancestor regions. An fpga-mgr property + in a region will override any inherited FPGA manager. + + partial-fpga-config: + type: boolean + description: + Set if partial reconfiguration is to be done, otherwise full + reconfiguration is done. + + region-freeze-timeout-us: + description: + The maximum time in microseconds to wait for bridges to successfully + become disabled before the region has been programmed. + + region-unfreeze-timeout-us: + description: + The maximum time in microseconds to wait for bridges to successfully + become enabled after the region has been programmed. + +required: + - compatible + - fpga-mgr + +additionalProperties: + type: object + +examples: + - | + /* + * Full Reconfiguration without Bridges with DT overlay + */ + fpga_region0: fpga-region@0 { + compatible = "fpga-region"; + reg = <0 0>; + #address-cells = <1>; + #size-cells = <1>; + fpga-mgr = <&fpga_mgr0>; + ranges = <0x10000000 0x20000000 0x10000000>; + + /* DT Overlay contains: &fpga_region0 */ + firmware-name = "zynq-gpio.bin"; + gpio@40000000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0x40000000 0x10000>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + - | + /* + * Partial reconfiguration with bridge + */ + fpga_region1: fpga-region@0 { + compatible = "fpga-region"; + reg = <0 0>; + ranges; + #address-cells = <1>; + #size-cells = <1>; + fpga-mgr = <&fpga_mgr1>; + fpga-bridges = <&fpga_bridge1>; + partial-fpga-config; + + /* DT Overlay contains: &fpga_region1 */ + firmware-name = "zynq-gpio-partial.bin"; + clk: clock { + compatible = "fixed-factor-clock"; + clocks = <&parentclk>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + }; + axi { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + gpio@40000000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0x40000000 0x10000>; + #gpio-cells = <2>; + gpio-controller; + clocks = <&clk>; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/fpga/xlnx,afi-fpga.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/fpga/xlnx,afi-fpga.txt @@ -0,0 +1,67 @@ +Xilinx ZynqMp AFI interface Manager + +The Zynq UltraScale+ MPSoC Processing System core provides access from PL +masters to PS internal peripherals, and memory through AXI FIFO interface +(AFI) interfaces. + +Required properties: +-compatible: Should contain "xlnx,afi-fpga" +-config-afi: Pairs of + +The possible values of regid and values are + regid: Regids of the register to be written possible values + 0- AFIFM0_RDCTRL + 1- AFIFM0_WRCTRL + 2- AFIFM1_RDCTRL + 3- AFIFM1_WRCTRL + 4- AFIFM2_RDCTRL + 5- AFIFM2_WRCTRL + 6- AFIFM3_RDCTRL + 7- AFIFM3_WRCTRL + 8- AFIFM4_RDCTRL + 9- AFIFM4_WRCTRL + 10- AFIFM5_RDCTRL + 11- AFIFM5_WRCTRL + 12- AFIFM6_RDCTRL + 13- AFIFM6_WRCTRL + 14- AFIFS + 15- AFIFS_SS2 +- value: Array of values to be written. + for FM0_RDCTRL(0) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM0_WRCTRL(1) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM1_RDCTRL(2) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM1_WRCTRL(3) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM2_RDCTRL(4) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM2_WRCTRL(5) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM3_RDCTRL(6) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM3_WRCTRL(7) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM4_RDCTRL(8) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM4_WRCTRL(9) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM5_RDCTRL(10) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM5_WRCTRL(11) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM6_RDCTRL(12) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for FM6_WRCTRL(13) the valid values-fabric width 2: 32-bit,1 : 64-bit ,0: 128-bit enabled + for AFI_FA(14) + dw_ss1_sel bits (11:10) + dw_ss0_sel bits (9:8) + 0x0: 32-bit AXI data width), + 0x1: 64-bit AXI data width, + 0x2: 128-bit AXI data + All other bits are 0 write ignored. + + for AFI_FA(15) selects for ss2AXI data width valid values + 0x000: 32-bit AXI data width), + 0x100: 64-bit AXI data width, + 0x200: 128-bit AXI data + +Optional properties: +- resets : Phandle and reset specifier for the ps-pl reset. + See ../reset/reset.txt for details. + +Example: +afi0: afi0 { + compatible = "xlnx,afi-fpga"; + config-afi = <0 2>, <1 1>, <2 1>; + resets = <&zynqmp_reset 116>, <&zynqmp_reset 117>, + <&zynqmp_reset 118>, <&zynqmp_reset 119>; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/fpga/xlnx,versal-fpga.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/fpga/xlnx,versal-fpga.yaml @@ -26,7 +26,7 @@ examples: - | - versal_fpga: versal_fpga { + versal_fpga: versal-fpga { compatible = "xlnx,versal-fpga"; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/fpga/xlnx,zynq-afi-fpga.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/fpga/xlnx,zynq-afi-fpga.txt @@ -0,0 +1,19 @@ +Xilinx Zynq AFI interface Manager + +The Zynq Processing System core provides access from PL masters to PS +internal peripherals, and memory through AXI FIFO interface +(AFI) interfaces. + +Required properties: +-compatible: Should contain "xlnx,zynq-afi-fpga" +-reg: Physical base address and size of the controller's register area. +-xlnx,afi-buswidth : Size of the afi bus width. + 0: 64-bit AXI data width, + 1: 32-bit AXI data width, + +Example: +afi0: afi0 { + compatible = "xlnx,zynq-afi-fpga"; + reg = <0xf8008000 0x1000>; + xlnx,afi-buswidth = <1>; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/hwmon/tps544.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/hwmon/tps544.txt @@ -0,0 +1,14 @@ +TPS544B25 power regulator + +This power regulator driver supports voltage read/write and +current calibration and readback. + +Required properties: +- compatible: should be "ti,tps544" +- reg: I2C slave address + +Example: +tps544@24 { + compatible = "ti,tps544"; + reg = <0x24>; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml @@ -75,7 +75,7 @@ - clocks allOf: - - $ref: i2c-controller.yaml + - $ref: /schemas/i2c/i2c-controller.yaml# - if: properties: compatible: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml @@ -21,7 +21,7 @@ google,cros-ec-spi or google,cros-ec-i2c. allOf: - - $ref: i2c-controller.yaml# + - $ref: /schemas/i2c/i2c-controller.yaml# properties: compatible: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml @@ -28,6 +28,9 @@ reg: maxItems: 1 + clocks: + maxItems: 1 + dmas: maxItems: 1 @@ -39,12 +42,16 @@ $ref: /schemas/types.yaml#/definitions/phandle description: A reference to a the actual ADC to which this FPGA ADC interfaces to. + deprecated: true + + '#io-backend-cells': + const: 0 required: - compatible - dmas - reg - - adi,adc-dev + - clocks additionalProperties: false @@ -55,7 +62,7 @@ reg = <0x44a00000 0x10000>; dmas = <&rx_dma 0>; dma-names = "rx"; - - adi,adc-dev = <&spi_adc>; + clocks = <&axi_clk>; + #io-backend-cells = <0>; }; ... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/iio/adc/ti,ina260.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/iio/adc/ti,ina260.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ina260.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments INA260 power monitor + +maintainers: + - Shubhrajyoti Datta + +description: | + The INA260 is a digital-output, current, power and voltage monitor + with an I2C and SMBUS compatible interface with an integrated shunt + resistor. It features up to 16 programmable addresses on I2C compatible + interface. Datasheet - https://www.ti.com/lit/ds/symlink/ina260.pdf?ts=1608607288391 + +properties: + compatible: + enum: + - ti,ina260 + + reg: + description: | + The 7-bits long I2c address of the device + + "#io-channel-cells": + const: 1 + + interrupts: + description: | + IRQ line for the device + + label: + description: | + A symbolic name for the device + +required: + - compatible + - reg + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ina260@40 { + compatible = "ti,ina260"; + reg = <0x40>; + #io-channel-cells = <1>; + }; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml @@ -0,0 +1,159 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2019 - 2020 Xilinx Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/xlnx,versal-sysmon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Versal Sysmon Linux Driver + +maintainers: + - Salih Erim + +description: | + Sysmon Driver uses Linux IIO framework which was used to abstract the supply + voltages and temperatures across the chip as Voltage and Temperature + Channels in the framework. Since there are only 160 supply voltage registers + and 184 measurement points, there is no constant mapping of supply voltage + registers and the measurement points. User has to select the voltages to + monitor in design tool. Depending on the selection, a voltage supply gets + mapped to one of the supply registers. So, this mapping information is + provided to the driver via a device tree. Depending on the number of supplies + enabled in the design, the device tree will contain the information of name + of the supply enabled and the supply register it maps to. + +properties: + compatible: + items: + - enum: + - xlnx,versal-sysmon + + reg: + description: Sysmon Registers + maxItems: 1 + + interrupts: + description: interrupt line for Sysmon + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + '#io-channel-cells': + const: 0 + + xlnx,numchannels: + $ref: /schemas/types.yaml#/definitions/uint8 + description: | + Number of supply channels enabled in the design. + Possible values 0 - 160. Based on this value, child supply nodes will + be created + + xlnx,nodeid: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + PLM specified sysmon node id. + + xlnx,hbm: + description: | + Exists if node refers to a HBM SLR. + type: boolean + +patternProperties: + "^supply@([0-9]{1,2}|1[0-5][0-9])$": + type: object + description: | + Represents the supplies configured in the design. + + properties: + reg: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 159 + description: + The supply number associated with the voltage. + + xlnx,name: + $ref: /schemas/types.yaml#/definitions/string + description: + Name of the supply enabled + + xlnx,bipolar: + $ref: /schemas/types.yaml#/definitions/flag + description: + If the supply has a bipolar type and the output will be signed + + required: + - reg + - xlnx,name + + additionalProperties: false + +required: + - compatible + - reg + - xlnx,numchannels + +additionalProperties: false + +examples: + - | + #include + bus { + #address-cells = <2>; + #size-cells = <2>; + + sysmon@f1270000 { + compatible = "xlnx,versal-sysmon"; + reg = <0 0xf1270000 0 0x4000>; + interrupts = <0 0x90 0x4>; + xlnx,numchannels = /bits/8 <8>; + xlnx,nodeid = ; + #address-cells = <1>; + #size-cells = <0>; + supply@0 { + reg = <0>; + xlnx,name = "vccint"; + }; + + supply@31 { + reg = <31>; + xlnx,name = "vccsoc"; + }; + + supply@32 { + reg = <32>; + xlnx,bipolar; + xlnx,name = "vccram"; + }; + + supply@63 { + reg = <63>; + xlnx,bipolar; + xlnx,name = "vccaux"; + }; + + supply@64 { + reg = <64>; + xlnx,name = "vccbram"; + }; + + supply@95 { + reg = <95>; + xlnx,name = "gt_avaux"; + }; + + supply@96 { + reg = <96>; + xlnx,name = "gt_vccaux"; + }; + + supply@159 { + reg = <159>; + xlnx,name = "vccint_ir"; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/iio/health/maxim,max30102.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/iio/health/maxim,max30102.yaml @@ -42,7 +42,7 @@ properties: compatible: contains: - const: maxim,max30100 + const: maxim,max30102 then: properties: maxim,green-led-current-microamp: false --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/interrupt-controller/xilinx,intc.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/interrupt-controller/xilinx,intc.txt @@ -0,0 +1,56 @@ +Xilinx Interrupt Controller + +The controller is a soft IP core that is configured at build time for the +number of interrupts and the type of each interrupt. These details cannot +be changed at run time. + +Required properties: + +- compatible : should be "xlnx,xps-intc-1.00.a" +- reg : Specifies base physical address and size of the registers. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value shall be a minimum of 1. + The Xilinx device trees typically use 2 but the 2nd value + is not used. +- xlnx,kind-of-intr : A 32 bit value specifying the interrupt type for each + possible interrupt (1 = edge, 0 = level). The interrupt + type typically comes in thru the device tree node of + the interrupt generating device, but in this case + the interrupt type is determined by the interrupt + controller based on how it was implemented. +- xlnx,num-intr-inputs: Specifies the number of interrupts supported + by the specific implementation of the controller (1-32). + +Optional properties: +- interrupt-parent : Specifies an interrupt controller from which it is + chained (cascaded). +- interrupts : Specifies the interrupt of the parent controller from which + it is chained. + +Example: + +axi_intc_0: interrupt-controller@41800000 { + #interrupt-cells = <2>; + compatible = "xlnx,xps-intc-1.00.a"; + interrupt-controller; + reg = <0x41800000 0x10000>; + xlnx,kind-of-intr = <0x1>; + xlnx,num-intr-inputs = <0x1>; +}; + +Chained Example: + +The interrupt is chained to hardware interrupt 61 (29 + 32) of the GIC +for Zynq. + +axi_intc_0: interrupt-controller@41800000 { + #interrupt-cells = <2>; + compatible = "xlnx,xps-intc-1.00.a"; + interrupt-controller; + interrupt-parent = <&ps7_scugic_0>; + interrupts = <0 29 4>; + reg = <0x41800000 0x10000>; + xlnx,kind-of-intr = <0x1>; + xlnx,num-intr-inputs = <0x1>; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/iommu/arm,smmu.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/iommu/arm,smmu.yaml @@ -484,7 +484,12 @@ - if: properties: compatible: - const: qcom,sm8450-smmu-500 + items: + - const: qcom,sm8450-smmu-500 + - const: qcom,adreno-smmu + - const: qcom,smmu-500 + - const: arm,mmu-500 + then: properties: clock-names: @@ -508,7 +513,11 @@ - if: properties: compatible: - const: qcom,sm8550-smmu-500 + items: + - const: qcom,sm8550-smmu-500 + - const: qcom,adreno-smmu + - const: qcom,smmu-500 + - const: arm,mmu-500 then: properties: clock-names: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/i2c/onnn,ap1302.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/i2c/onnn,ap1302.yaml @@ -0,0 +1,202 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/onnn,ap1302.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ON Semiconductor AP1302 Advanced Image Coprocessor + +maintainers: + - Laurent Pinchart + - Anil Kumar M + +description: |- + The AP1302 is a standalone ISP for ON Semiconductor sensors. It interfaces to + up to two RAW CMOS sensors over MIPI CSI-2 connections, processes the two + video streams and outputs YUV frames to the host over a MIPI CSI-2 interface. + Frames are output side by side or on two virtual channels. + + The sensors must be identical. They are connected to the AP1302 on dedicated + I2C buses, and are controlled by the AP1302 firmware. They are not accessible + from the host. + +properties: + compatible: + const: onnn,ap1302 + + reg: + description: I2C device address. + maxItems: 1 + + clocks: + description: Reference to the CLK clock. + maxItems: 1 + + reset-gpios: + description: Reference to the GPIO connected to the RST pin (active low). + maxItems: 1 + + standby-gpios: + description: + Reference to the GPIO connected to the STANDBY pin (active high). + maxItems: 1 + + port: + $ref: /schemas/graph.yaml#/$defs/port-base + unevaluatedProperties: false + description: MIPI CSI-2 output interface to the host. + + properties: + endpoint: + $ref: /schemas/graph.yaml#/$defs/endpoint-base + unevaluatedProperties: false + + properties: + clock-noncontinuous: + type: boolean + + data-lanes: + oneOf: + - items: + - const: 1 + - items: + - const: 1 + - const: 2 + - items: + - const: 1 + - const: 2 + - const: 3 + - const: 4 + + required: + - data-lanes + + sensors: + type: object + description: List of connected sensors + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + onnn,model: + $ref: /schemas/types.yaml#/definitions/string + description: | + Model of the connected sensors. Must be a valid compatible string. + + If no sensor is connected, this property must no be specified, and + the AP1302 can be used with it's internal test pattern generator. + + patternProperties: + "^sensor@[01]": + type: object + description: | + Sensors connected to the first and second input, with one node per + sensor. + + properties: + reg: + description: AP1302 input port number + maxItems: 1 + + patternProperties: + ".*-supply": + description: Power supplies for the sensor + + required: + - reg + + additionalProperties: false + + required: + - "#address-cells" + - "#size-cells" + + # How can we express that onnn,model requires one sensor object to be set ? + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - port + - sensors + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + camera@3c { + compatible = "onnn,ap1302"; + reg = <0x3c>; + + clocks = <&clk24mhz>; + + reset-gpios = <&pio 102 GPIO_ACTIVE_LOW>; + standby-gpios = <&pio 40 GPIO_ACTIVE_HIGH>; + + port { + isp1_out: endpoint { + remote-endpoint = <&seninf_in1>; + data-lanes = <1 2 3 4>; + }; + }; + + sensors { + #address-cells = <1>; + #size-cells = <0>; + + onnn,model = "onnn,ar0144"; + + sensor@0 { + reg = <0>; + + vdd-supply = <&mt6358_vcamd_reg>; + vaa-supply = <&mt6358_vcama1_reg>; + vddio-supply = <®_1p8v_ext>; + }; + }; + }; + }; + + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + camera@3c { + compatible = "onnn,ap1302"; + reg = <0x3c>; + + clocks = <&topckgen 0>; + + reset-gpios = <&pio 102 GPIO_ACTIVE_LOW>; + standby-gpios = <&pio 40 GPIO_ACTIVE_HIGH>; + + port { + isp2_out: endpoint { + remote-endpoint = <&seninf_in1>; + data-lanes = <1 2>; + }; + }; + + sensors { + #address-cells = <1>; + #size-cells = <0>; + }; + }; + }; + +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml @@ -37,15 +37,15 @@ active low. maxItems: 1 - dovdd-supply: + DOVDD-supply: description: Definition of the regulator used as interface power supply. - avdd-supply: + AVDD-supply: description: Definition of the regulator used as analog power supply. - dvdd-supply: + DVDD-supply: description: Definition of the regulator used as digital power supply. @@ -59,9 +59,9 @@ - reg - clocks - clock-names - - dovdd-supply - - avdd-supply - - dvdd-supply + - DOVDD-supply + - AVDD-supply + - DVDD-supply - reset-gpios - port @@ -82,9 +82,9 @@ clock-names = "xvclk"; reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; - dovdd-supply = <&sw2_reg>; - dvdd-supply = <&sw2_reg>; - avdd-supply = <®_peri_3p15v>; + DOVDD-supply = <&sw2_reg>; + DVDD-supply = <&sw2_reg>; + AVDD-supply = <®_peri_3p15v>; port { ov2680_to_mipi: endpoint { --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml @@ -36,7 +36,7 @@ properties: port@0: - $ref: /schemas/graph.yaml#/$defs/port-base + $ref: /schemas/graph.yaml#/properties/port description: Analog input port properties: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,axis-broadcaster.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,axis-broadcaster.yaml @@ -0,0 +1,179 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/xilinx/xlnx,axis-broadcaster.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx AXI4-Stream Broadcaster + +maintainers: + - Ronak Shah + +description: | + The AXI4-Stream Broadcaster provides a solution for replicating a single + inbound AXI4-Stream interface into multiple outbound AXI4-Stream interfaces. + Support for up to 16 outbound AXI4-Stream interfaces is provided. + For more details, Please refer to PG085 AXI4-Stream Infrastructure IP Suite. + +properties: + compatible: + items: + - enum: + - xlnx,axis-broadcaster-1.1 + + # See ./video-interfaces.txt for details + ports: + type: object + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + port@0: + type: object + description: | + Input/sink port node, describing module connected to the + input of AXI4-Stream Broadcaster. + + properties: + reg: + description: | + Input/sink port number. + const: 0 + + endpoint: + type: object + + properties: + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + required: + - reg + - endpoint + + additionalProperties: false + + patternProperties: + "^port@([1-9]|1[0-6])$": + type: object + description: | + Output/source port node, describing module connected to the + output of AXI4-Stream Broadcaster. + + properties: + reg: + description: | + Output/source port number. It can have min 2 ports and + max 16 ports, numbered from 1 to 16. + items: + minimum: 1 + maximum: 16 + + endpoint: + type: object + + properties: + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + required: + - reg + - endpoint + + additionalProperties: false + + required: + - "#address-cells" + - "#size-cells" + - port@0 + - port@1 + - port@2 + + additionalProperties: false + +required: + - compatible + - ports + +additionalProperties: false + +examples: + - | + axis_broadcaster_0 { + compatible = "xlnx,axis-broadcaster-1.1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + /* Sink port */ + reg = <0>; + axis_broad_0_in: endpoint { + remote-endpoint = <&v_proc_ss_out>; + }; + }; + port@1 { + /* Source port */ + reg = <1>; + axis_broad_0_out1: endpoint { + remote-endpoint = <&v_frmbuf_wr_0_in>; + }; + }; + port@2 { + /* Source port */ + reg = <2>; + axis_broad_0_out2: endpoint { + remote-endpoint = <&v_frmbuf_wr_1_in>; + }; + }; + port@3 { + /* Source port */ + reg = <3>; + axis_broad_0_out3: endpoint { + remote-endpoint = <&v_frmbuf_wr_2_in>; + }; + }; + port@4 { + /* Source port */ + reg = <4>; + axis_broad_0_out4: endpoint { + remote-endpoint = <&v_frmbuf_wr_3_in>; + }; + }; + port@5 { + /* Source port */ + reg = <5>; + axis_broad_0_out5: endpoint { + remote-endpoint = <&v_frmbuf_wr_4_in>; + }; + }; + port@6 { + /* Source port */ + reg = <6>; + axis_broad_0_out6: endpoint { + remote-endpoint = <&v_frmbuf_wr_5_in>; + }; + }; + port@7 { + /* Source port */ + reg = <7>; + axis_broad_0_out7: endpoint { + remote-endpoint = <&v_frmbuf_wr_6_in>; + }; + }; + }; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,axis-subsetconv.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,axis-subsetconv.yaml @@ -0,0 +1,133 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/xilinx/xlnx,axis-subsetconv.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Subset Converter + +maintainers: + - Anil Kumar Mamidala + - Karthikeyan T + +description: | + This subset converter driver is for the Xilinx subset converter + IP which is a non-memory mapped IP used for converting formats. + The format conversion of source pad and sink pad in the pipeline + done by subset converter IP will be mapped in this driver. + +properties: + compatible: + items: + - enum: + - xlnx,axis-subsetconv-1.1 + + # See ./video-interfaces.txt for details + ports: + type: object + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + port@0: + type: object + description: | + Input/sink port node, describing module connected to the + input of AXI4-Stream Subset Converter. + + properties: + reg: + description: | + Input/sink port number. + const: 0 + + endpoint: + type: object + + properties: + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + required: + - reg + - endpoint + + additionalProperties: false + + patternProperties: + "port@1": + type: object + description: | + Output/source port node, describing module connected to the + output. + + properties: + reg: + description: | + Output/source port number. + + endpoint: + type: object + + properties: + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + required: + - reg + - endpoint + + additionalProperties: false + + required: + - "#address-cells" + - "#size-cells" + - port@0 + - port@1 + + additionalProperties: false + +required: + - compatible + - ports + +additionalProperties: false + +examples: + - | + axis_subsetconv_0 { + compatible = "xlnx,axis-subsetconv-1.1"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + /* Sink port */ + reg = <0>; + subset_conv_in: endpoint { + remote-endpoint = <&isp_csiss_out>; + }; + }; + port@1 { + /* Source port */ + reg = <1>; + subset_conv_out: endpoint { + remote-endpoint = <&isp_vcap_csi_in>; + }; + }; + }; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml @@ -50,6 +50,7 @@ Packets other than this data type (except for RAW8 and User defined data types) will be filtered out. Possible values are as below - + 0x18 - YUV4208B 0x1e - YUV4228B 0x1f - YUV42210B 0x20 - RGB444 @@ -67,6 +68,7 @@ 0x2f - RAW20 $ref: /schemas/types.yaml#/definitions/uint32 oneOf: + - const: 0x18 - minimum: 0x1e maximum: 0x24 - minimum: 0x28 --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,isppipeline.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,isppipeline.yaml @@ -0,0 +1,271 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/xilinx/xlnx,isppipeline.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Video ISP Pipeline IP + +maintainers: + - Kaushal Kumar + - Venkat Praveen Kancharlapalli + - Mounik Katikala + +description: | + The Xilinx Video ISP pipeline IP is used to interface to a bayer video source. + It is a pipeline of image processing functions, such as black level correction, bad pixel correction, + gain control, auto-white balance, gamma correction etc., processing the raw video from the sensor. + Gamma_lut array values are computed using compute_gamma function whose link is mentioned below: + https://github.com/Xilinx/Vitis_Libraries/blob/de67b58ca9c7f4a76411103c0ecf9d467731b476/vision/L1/examples/isppipeline/xf_isp_tb.cpp#L313 + Link to product guide for ISP pipeline is mentioned below: + https://docs.amd.com/r/en-US/Vitis_Libraries/vision/index.html + +properties: + compatible: + enum: + - xlnx,isppipeline-1.0 + - xlnx,isppipeline-2.0 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: Reference to the AXI Streaming clock. + + clock-names: + items: + - const: ap_clk + + xlnx,max-height: + $ref: /schemas/types.yaml#/definitions/uint16 + description: Maximum number of lines. + minimum: 64 + maximum: 4320 + + xlnx,max-width: + $ref: /schemas/types.yaml#/definitions/uint16 + description: Maximum number of pixels in a line. + minimum: 64 + maximum: 8192 + + xlnx,rgain: + $ref: /schemas/types.yaml#/definitions/uint16 + description: To configure gain value for the red channel. + minimum: 0 + maximum: 65535 + + xlnx,bgain: + $ref: /schemas/types.yaml#/definitions/uint16 + description: To configure gain value for the blue channel. + minimum: 0 + maximum: 65535 + + xlnx,pawb: + $ref: /schemas/types.yaml#/definitions/uint16 + description: | + It is used in calculating the threshold value, which is used in gray world + white balance method to compute average pixel values below the threshold value. + minimum: 0 + maximum: 65535 + + xlnx,mode-reg: + type: boolean + description: Flag to enable/disable AWB algorithm + + reset-gpios: + maxItems: 1 + description: Specifier for GPIO that asserts ISP pipeline IP. Use GPIO_ACTIVE_LOW on ap_rst_n. + + ports: + type: object + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + port@0: + type: object + description: | + Input/sink port node, describing module connected to the + input of ISP pipeline IP. + + properties: + reg: + description: | + Input/sink port number. + const: 0 + + endpoint: + type: object + + properties: + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + xlnx,video-width: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Width of the video data in bits + enum: [8, 10, 12, 16] + default: 10 + + required: + - reg + - endpoint + + additionalProperties: false + + "port@1": + type: object + description: | + Output/source port node, describing module connected to the + output. + + properties: + reg: + description: | + Output/source port number. + const: 1 + + endpoint: + type: object + + properties: + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + xlnx,video-width: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Width of the video data in bits + enum: [8, 10, 12, 16] + default: 8 + + required: + - reg + - endpoint + + additionalProperties: false + + required: + - "#address-cells" + - "#size-cells" + - port@0 + - port@1 + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - reset-gpios + - ports + +additionalProperties: false + +allOf: + - if: + properties: + compatible: + contains: + const: xlnx,isppipeline-1.0 + then: + required: + - xlnx,max-height + - xlnx,max-width + - xlnx,rgain + - xlnx,bgain + - xlnx,pawb + - xlnx,mode-reg + + - if: + properties: + compatible: + contains: + const: xlnx,isppipeline-2.0 + then: + properties: + ports: + properties: + port@0: + required: + - xlnx,video-width + port@1: + required: + - xlnx,video-width + +examples: + - | + ISPPipeline0: ISPPipeline@a40c0000 { + compatible = "xlnx,isppipeline-1.0"; + reg = <0xa40c0000 0x10000>; + clocks = <&misc_clk_0>; + clock-names = "ap_clk"; + reset-gpios = <&gpio 87 1>; + xlnx,max-width = /bits/ 16 <3840>; + xlnx,max-height = /bits/ 16 <2160>; + xlnx,rgain = /bits/ 16 <128>; + xlnx,bgain = /bits/ 16 <210>; + xlnx,pawb = /bits/ 16 <350>; + xlnx,mode-reg; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + /* Sink port */ + reg = <0>; + isppipeline0_in: endpoint { + remote-endpoint = <&isp_csiss_out>; + }; + }; + port@1 { + /* Source port */ + reg = <1>; + isppipeline0_out: endpoint { + remote-endpoint = <&isp_vcap_csi_in>; + }; + }; + }; + }; + + - | + ISPPipeline1: ISPPipeline@a40f0000 { + compatible = "xlnx,isppipeline-2.0"; + reg = <0xa40f0000 0x10000>; + clocks = <&misc_clk_0>; + reset-gpios = <&gpio0 27 1>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + /* Sink port */ + reg = <0>; + xlnx,video-width = <10>; + isppipeline1_in: endpoint { + remote-endpoint = <&isp_csiss_out>; + }; + }; + + port@1 { + /* Source port */ + reg = <1>; + xlnx,video-width = <8>; + isppipeline1_out: endpoint { + remote-endpoint = <&isp_vcap_csi_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,mem2mem.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,mem2mem.txt @@ -0,0 +1,25 @@ +Xilinx Video IP MEM2MEM Pipeline (XVIM2M) +---------------------------------------- + +Xilinx video IP mem2mem pipeline processes DMA transfers to achieve memory +copy from one physical memory to other. The data is copied by employing two +DMA transfers memory to device and device to memory transactions one after +the other. The DT node of the XVIM2M represents as a top level node of the +pipeline and defines mappings between DMAs. + +Required properties: + +- compatible: Must be "xlnx,mem2mem". + +- dmas, dma-names: List of two DMA specifier and identifier strings (as + defined in Documentation/devicetree/bindings/dma/dma.txt) per port. + Identifier string of one DMA channel should be "tx" and other should be + "rx". + +Example: + + video_m2m { + compatible = "xlnx,mem2mem"; + dmas = <&dma_1 0>, <&dma_2 0>; + dma-names = "tx", "rx"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,sdirxss.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,sdirxss.txt @@ -0,0 +1,77 @@ + +Xilinx SDI Receiver Subsystem +------------------------------ + +The Xilinx SDI Rx Subsystem is used to capture SDI Video in upto 12G mode. +It outputs the video as an AXI4 Stream video data in YUV 422 10bpc mode. +The subsystem consists of the SDI Rx IP whose SDI native output is connected +to a SDI to Native conversion Bridge. The output of the Native bridge is +connected to a Native to AXI4S Bridge which generates the AXI4 Stream of +YUV422 or YUV420 10 bpc in dual pixel per clock. + +Required properties: + +- compatible: Must contain "xlnx,v-smpte-uhdsdi-rx-ss" + +- reg: Physical base address and length of the registers set for the device. + +- interrupts: Contains the interrupt line number. + +- interrupt-parent: phandle to interrupt controller. + +- xlnx,include-edh: Whether the EDH processor is enabled in design or not. + +- xlnx,line-rate: The maximum mode supported by the design. + +- clocks: Input clock specifier. Refer to common clock bindings. + +- clock-names: List of input clocks. + Required elements: "s_axi_aclk", "sdi_rx_clk", "video_out_clk" + +- port: Video port, using the DT bindings defined in ../video-interfaces.txt. + The SDI Rx subsystem has one port configured as output port. + +- xlnx,video-format, xlnx,video-width: Video format and width, as defined in + video.txt. Please note that the video format is fixed to either YUV422 or YUV420 + and the video-width is 10. + +Optional properties: + +- reset_gt-gpios: contains GPIO reset phandle for FMC init done pin in GT. + This pin is active low. +- picxo_reset-gpios: contains GPIO reset phandle for PICXO done pin for PICXO module. + This pin is active high. +- xlnx,bpp: This denotes the bit depth as 10 or 12 based on IP configuration. + The default value is 10 for backward compatibility. + +Example: + v_smpte_uhdsdi_rx_ss: v_smpte_uhdsdi_rx_ss@80000000 { + compatible = "xlnx,v-smpte-uhdsdi-rx-ss"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; + reg = <0x0 0x80000000 0x0 0x10000>; + xlnx,include-axilite = "true"; + xlnx,include-edh = "true"; + xlnx,include-vid-over-axi = "true"; + xlnx,line-rate = "12G_SDI_8DS"; + clocks = <&clk_1>, <&si570_1>, <&clk_2>; + clock-names = "s_axi_aclk", "sdi_rx_clk", "video_out_clk"; + reset_gt-gpios = <&axi_gpio_0 0 0 GPIO_ACTIVE_LOW>; + picxo_reset-gpios = <&axi_gpio_0 2 0 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <10>; + + sdirx_out: endpoint { + remote-endpoint = <&vcap_sdirx_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-axi4s-switch.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-axi4s-switch.txt @@ -0,0 +1,141 @@ +Xilinx AXI4-Stream Switch +------------------------------- + +The AXI4-Stream Switch provides configurable routing between masters and slaves. +It supports up to 16 masters/sources and 16 slaves/sinks and two routing options. +There is atleast one slave/sink port and two master/source ports. + +The two routing options available are TDEST routing and control register routing. +The TDEST based routing uses design parameters and hence there no software control. +Each port is mapped as a pad and has its own format specified. + +Control register routing introduces an AXI4-Lite interface to configure the +routing table. There is one register for each of the master interfaces to +control each of the selectors. This routing mode requires that there is +precisely only one path between master and slave. When attempting to map the +same slave interface to multiple master interfaces, only the lowest master +interface is able to access the slave interface. +Here only the slave/sink ports have formats as master/source ports will inherit +the corresponding slave ports formats. A routing table is maintained in this case. + +Please refer to PG085 AXI4-Stream Infrastructure IP Suite v2.2 for more details. + +Required properties: + + - compatible: Must be "xlnx,axis-switch-1.1". + - xlnx,routing-mode: Can be 0 (TDEST routing) or 1 (Control reg routing) + - xlnx,num-si-slots: Number of slave / input ports. Min 1 Max 16 . + - xlnx,num-mi-slots: Number of master / output ports. Min 1 Max 16. + - ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + - clocks: Reference to the AXI Streaming clock feeding the ACLK and + AXI4 Lite control interface clock when control routing is enabled. + - clock-names: Must have "aclk". + +Optional properties: + - reg: Physical base address and length of the registers set for the device. + This is required only if xlnx,routing-mode is 1. + - clocks: Reference to AXI4 Lite control interface clock when routing-mode is 1. + - clock-names: "s_axi_ctl_clk" clock for AXI4 Lite interface when routing-mode is 1. + +Example: + +For TDEST routing, from 1 slave port to 4 master ports + + axis_switch_0: axis_switch@0 { + compatible = "xlnx,axis-switch-1.1"; + xlnx,routing-mode = <0x0>; + xlnx,num-si-slots = <0x1>; + xlnx,num-mi-slots = <0x4>; + clocks = <&vid_stream_clk>; + clock-names = "aclk"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + switch_in0: endpoint { + remote-endpoint = <&csirxss_out>; + }; + }; + port@1 { + reg = <1>; + switch_out0: endpoint { + remote-endpoint = <&vcap_csirxss0_in>; + }; + }; + port@2 { + reg = <2>; + switch_out1: endpoint { + remote-endpoint = <&vcap_csirxss1_in>; + }; + }; + port@3 { + reg = <3>; + switch_out2: endpoint { + remote-endpoint = <&vcap_csirxss2_in>; + }; + }; + port@4 { + reg = <4>; + switch_out3: endpoint { + remote-endpoint = <&vcap_csirxss3_in>; + }; + }; + }; + + }; + +For Control reg based routing, from 2 slave ports to 4 master ports + + axis_switch_0: axis_switch@a0050000 { + compatible = "xlnx,axis-switch-1.1"; + reg = <0x0 0xa0050000 0x0 0x1000>; + xlnx,routing-mode = <0x1>; + xlnx,num-si-slots = <0x2>; + xlnx,num-mi-slots = <0x4>; + clocks = <&vid_stream_clk>, <&misc_clk_0>; + clock-names = "aclk", "s_axi_ctl_clk; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + switch_in0: endpoint { + remote-endpoint = <&csirxss_out>; + }; + }; + port@1 { + reg = <1>; + switch_in1: endpoint { + remote-endpoint = <&tpg_out>; + }; + }; + port@2 { + reg = <2>; + switch_out0: endpoint { + remote-endpoint = <&vcap_csirxss0_in>; + }; + }; + port@3 { + reg = <3>; + switch_out1: endpoint { + remote-endpoint = <&vcap_csirxss1_in>; + }; + }; + port@4 { + reg = <4>; + switch_out2: endpoint { + remote-endpoint = <&vcap_csirxss2_in>; + }; + }; + port@5 { + reg = <5>; + switch_out3: endpoint { + remote-endpoint = <&vcap_csirxss3_in>; + }; + }; + }; + + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-cfa.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-cfa.txt @@ -0,0 +1,58 @@ +Xilinx Color Filter Array (CFA) +------------------------------- + +Required properties: + +- compatible: Must be "xlnx,v-cfa-7.0". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the video core clock. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The cfa has an input port (0) and an output port (1). + +Required port properties: + +- xlnx,video-format: Must be SENSOR_MONO for the input port (0), and RBG for + the output port (1). + +- xlnx,video-width: Video width as defined in video.txt + +- xlnx, cfa-pattern: Must be one of "rggb", "grbg", "gbrg", and "bggr" for the + input port (0). Must not be specified for the output port (1). + +Example: + + cfa_0: cfa@400b0000 { + compatible = "xlnx,v-cfa-7.0"; + reg = <0x400b0000 0x10000>; + clocks = <&clkc 15>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + xlnx,cfa-pattern = "rggb"; + + cfa0_in: endpoint { + remote-endpoint = <&spc0_out>; + }; + }; + port@1 { + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + cfa0_out: endpoint { + remote-endpoint = <&ccm0_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-cresample.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-cresample.txt @@ -0,0 +1,54 @@ +Xilinx Chroma Resampler (CRESAMPLE) +----------------------------------- + +Required properties: + +- compatible: Must be "xlnx,v-cresample-4.0". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the video core clock. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The cresample as han input port (0) and an output port (1). + +Required port properties: + +- xlnx,video-format: Must be one of YUV_444, YUV_422 or YUV_420 for the input + port (0), and one of YUV_422 or YUV_420 for the output port (1). + +- xlnx,video-width: Video width as defined in video.txt + +Example: + + cresample_0: cresample@40120000 { + compatible = "xlnx,v-cresample-4.0"; + reg = <0x40120000 0x10000>; + clocks = <&clkc 15>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + cresample0_in: endpoint { + remote-endpoint = <&rgb2yuv0_out>; + }; + }; + port@1 { + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + cresample0_out: endpoint { + remote-endpoint = <&scaler0_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-demosaic.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-demosaic.txt @@ -0,0 +1,62 @@ +Xilinx Video Demosaic IP +----------------------------- +The Xilinx Video Demosaic IP is used to interface to a Bayer video source. + +The driver set default Sink Pad media bus format to RGGB. +The IP and driver only support RGB as its Source Pad media format. + +Required properties: + +- compatible: Must be "xlnx,v-demosaic". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the AXI Streaming clock feeding the Demosaic ap_clk. + +- xlnx,max-height: Maximum number of lines. Valid range is 64 to 4320. + +- xlnx,max-width: Maximum number of pixels in a line. Valid range is 64 to 8192. + +- reset-gpios: Specifier for GPIO that asserts Demosaic IP (AP_RST_N) reset. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + +Required port properties: + +- reg: This value represents the media pad of the V4L2 sub-device. + A Sink Pad is represented by reg = <0> + A Source Pad is represented by reg = <1> + +- xlnx,video-width: Video width as defined in video.txt + +Example: + demosaic_1: demosaic@a00b0000 { + compatible = "xlnx,v-demosaic"; + reg = <0x0 0xa00b0000 0x0 0x10000>; + clocks = <&vid_stream_clk>; + reset-gpios = <&gpio 87 1>; + xlnx,max-width = <3840>; + xlnx,max-height = <2160>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + xlnx,video-width = <8>; + + demosaic_in: endpoint { + remote-endpoint = <&tpg_out>; + }; + }; + + port@1 { + reg = <1>; + xlnx,video-width = <8>; + + demosaic_out: endpoint { + remote-endpoint = <&gamma_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-dprxss.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-dprxss.yaml @@ -0,0 +1,210 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/xilinx/xlnx,v-dprxss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx DisplayPort Receiver Subsystem + +maintainers: + - Rajesh Gugulothu + +description: | + The DisplayPort subsystem is a full feature, hierarchically packaged + subsystem with a DisplayPort sink(RX). DP RX subsystem can capture + video data in different formats at different resolutions. + For more details, please refer to PG233 at + https://www.xilinx.com/support/documentation/ip_documentation/dp_rx_subsystem/v2_1/pg233-displayport-rx-subsystem.pdf + +properties: + compatible: + items: + - enum: + - xlnx,v-dp-rxss-3.1 + - xlnx,v-dp-rxss-3.0 + - const: xlnx,v-dp-rxss-3.0 + + interrupt-names: + items: + - const: dprxss_dp_irq + + reg: + minItems: 1 + items: + - description: DisplayPort Receiver Subsystem registers + - description: EDID IP block registers + + reg-names: + items: + - const: dp_base + - const: edid_base + + interrupts: + maxItems: 1 + + clocks: + description: List of clock specifiers + items: + - description: AXI Lite clock + - description: Link clock + - description: Video clock + + clock-names: + items: + - const: s_axi_aclk + - const: rx_lnk_clk + - const: rx_vid_clk + + phys: + description: This denotes phandles for phy lanes registered for DP + protocol. Number of phy lanes registered are depends on + the xlnx,lane-count property. + + phy-names: + items: + - const: dp-phy0 + - const: dp-phy1 + - const: dp-phy2 + - const: dp-phy3 + + xlnx,link-rate: + description: | + Max link rate that IP configured with.Possible values are as below - + 0x6 - 1.62 Gb/s + 0xa - 2.7 Gb/s + 0x14 - 5.4 Gb/s + 0x1e - 8.1 Gb/s + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0x6, 0xa, 0x14, 0x1e] + + xlnx,lane-count: + description: Max number of lanes that IP configured with. + Possible values are 1, 2, 4. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 4] + + xlnx,bpc: + description: | + Max BPC value that IP configured with. For example if IP is + configured + with 10 BPC means it supports (6, 8, 10) up to 10bpc. + Possible values are 6, 8, 10, 12, 16. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [6, 8, 10, 12, 16] + + xlnx,hdcp22-enable: + description: | + This denotes hdcp22 protocol is enabled in the IP. + $ref: /schemas/types.yaml#/definitions/uint32 + + xlnx,hdcp-enable: + description: | + This denotes hdcp1.4 protocol is enabled in the IP. + $ref: /schemas/types.yaml#/definitions/uint32 + + xlnx,audio-enable: + description: | + This denotes audio support has been enabled in the IP. + $ref: /schemas/types.yaml#/definitions/uint32 + + xlnx,audio-channels: + description: | + This denotes number of audio channels enabled in the IP + configuration. Possible values are 2, 3, 4, 5, 6, 7, 8. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [2, 3, 4, 5, 6, 7, 8] + + xlnx,hdcp1x-keymgmt: + description: + A phandle to a syscon device, used to access + hdcp1x keymgmt registers. + $ref: /schemas/types.yaml#/definitions/phandle + + ports: + type: object + + properties: + port@0: + type: object + description: | + Output / source port node, endpoint describing modules + connected the DisplayPort receiver + + properties: + reg: + const: 0 + + endpoint: + type: object + + properties: + + remote-endpoint: true + + required: + - remote-endpoint + + additionalProperties: false + + additionalProperties: false + +required: + - clock-names + - clocks + - compatible + - interrupts + - reg + - reg-names + - xlnx,link-rate + - xlnx,bpc + - xlnx,lane-count + - phy-names + - phys + - ports + +additionalProperties: false + +examples: + - | + v_dp_rxss1@a0040000 { + clock-names = "s_axi_aclk", "rx_lnk_clk", "rx_vid_clk" ; + clocks = <&zynqmp_clk 71>, <&zynqmp_clk 72>, <&misc_clk_1>; + compatible = "xlnx,v-dp-rxss-3.1", "xlnx,v-dp-rxss-3.0"; + interrupt-names = "dprxss_dp_irq"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; + reg = <0xa0040000 0x40000>, <0xa0010000 0x1000>; + reg-names = "dp_base", "edid_base"; + xlnx,link-rate = <0x1e>; + xlnx,audio-enable = <1>; + xlnx,audio-channels = <2>; + xlnx,bpc = <10>; + xlnx,hdcp22-enable = <1>; + xlnx,hdcp-enable = <1>; + xlnx,hdcp1x-keymgmt = <&hdcp_keymngmt_blk_0>; + xlnx,lane-count = <4>; + phy-names = "dp-phy0", "dp-phy1", "dp-phy2", "dp-phy3"; + phys = <&vphy_lane0 0 1 1 0>, <&vphy_lane1 0 1 1 0>, + <&vphy_lane2 0 1 1 0>, <&vphy_lane3 0 1 1 0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dp_rxss_out: endpoint { + remote-endpoint = <&remap0_in>; + }; + }; + }; + }; + hdcp_keymngmt_blk_0: hdcp_keymngmt_blk@a00c0000 { + compatible = "xlnx,hdcp-keymngmt-blk-1.0", "syscon"; + reg = <0xa00c0000 0x10000>; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-gamma-lut.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-gamma-lut.txt @@ -0,0 +1,63 @@ +Xilinx Video Gamma Correction IP +----------------------------------- +The Xilinx Video Gamma Correction IP is used to provide RGB gamma correction. +The IP provides a look up table for each R,G and B components. + +Required properties: + +- compatible: Must be "xlnx,v-gamma-lut". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the clock that drives the ap_clk + signal of Video Gamma Lookup. + +- xlnx,max-height: Maximum number of lines. Valid range is 64 to 4320. + +- xlnx,max-width: Maximum number of pixels in a line. Valid range is 64 to 8192. + +- reset-gpios: Specifier for a GPIO that asserts Gamma IP (AP_RST_N) reset + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The Gamma LUT IP has an input port (0) and an output port (1). + + +Required port properties: +- reg: This value represents the media pad of the V4L2 sub-device. + A Sink Pad is represented by reg = <0> + A Source Pad is represented by reg = <1> + +- xlnx,video-width: Video width as defined in video.txt. Can be either 8 or 10. + +Example: + + gamma_lut_1: gamma_lut_1@0xa0080000 { + compatible = "xlnx,v-gamma-lut"; + reg = <0x0 0xa0080000 0x0 0x10000>; + clocks = <&vid_stream_clk>; + reset-gpios = <&gpio 83 1>; + xlnx,max-height = <2160>; + xlnx,max-width = <3840>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + xlnx,video-width = <8>; + + gamma_in: endpoint { + remote-endpoint = <&demosaic_out>; + }; + }; + + port@1 { + reg = <1>; + xlnx,video-width = <8>; + + gamma_out: endpoint { + remote-endpoint = <&csc_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-hdmi-rxss1.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-hdmi-rxss1.yaml @@ -0,0 +1,247 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/xilinx/xlnx,v-hdmi-rxss1.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx HDMI 2.1 Receiver Subsystem + +maintainers: + - Vishal Sagar + +description: | + The Xilinx HDMI 2.1 Receiver Subsystem is a feature rich soft IP incorporating + all the necesssary logic to properly interface with PHY layer and provides HDMI + decoding functionality. The subsystem is a hierarchical IP that bundles a + collection of HDMI 2.1 Rx-related IP sub-cores and outputs them as a single IP. + The subsystem receives the captured TMDS data from the PHY layer. It then + extracts the video and audio streams from the HDMI stream and converts it to + video and audio streams. + For more details refer to PG 351 Xilinx HDMI 2.1 Rx Subsystem. + +properties: + compatible: + items: + - enum: + - xlnx,v-hdmi-rxss1-1.1 + - xlnx,v-hdmi-rxss1-1.2 + + reg: + maxItems: 1 + + interrupts: + maxItems: 5 + + interrupt-names: + description: Only irq is mandatory. Others are optional. + hdcp14_irq and hdcp14_timer_irq will be present when HDCP 1x is selected. + hdcp22_irq and hdcp22_timer_irq will be present when HDCP 2x is selected. + items: + - const: hdcp14_irq + - const: hdcp14_timer_irq + - const: hdcp22_irq + - const: hdcp22_timer_irq + - const: irq + + clocks: + items: + - description: Clock for AXI4-Lite control interface + - description: Fixed FRL Link clock + - description: AXI4-Stream clock + + clock-names: + items: + - const: s_axi_cpu_aclk + - const: frl_clk + - const: s_axis_video_aclk + + xlnx,edid-ram-size: + description: | + This is size of EDID in BRAM. + The possible values are 256, 512, 1024 or 4096. + This property has to be specified as '/bits/ 16' value. + $ref: /schemas/types.yaml#/definitions/uint16 + enum: [ 256, 512, 1024, 4096 ] + + xlnx,input-pixels-per-clock: + description: | + Number of pixels per clock on Video Interface. + This property has to be specified as '/bits/ 8' value. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [ 4, 8 ] + + xlnx,max-bits-per-component: + description: | + Maximum bits per component. + This property has to be specified as '/bits/ 8' value. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [ 8, 10, 12, 16 ] + + xlnx,max-frl-rate: + description: | + Maximum FRL rate. + This property has to be specified as '/bits/ 8' value. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [ 4, 5, 6 ] + + xlnx,frl-clk-freq-khz: + description: | + FRL clock frequency in KHz + $ref: /schemas/types.yaml#/definitions/uint32 + + xlnx,vid-clk-freq-khz: + description: | + Video clock frequency in KHz + $ref: /schemas/types.yaml#/definitions/uint32 + + xlnx,include-hdcp: + type: boolean + $ref: /schemas/types.yaml#/definitions/flag + description: | + Present when HDCP1x or HDCP2x is enabled. + + xlnx,include-hdcp-1-4: + type: boolean + $ref: /schemas/types.yaml#/definitions/flag + description: | + Present when HDCP1x is enabled. + + xlnx,include-hdcp-2-2: + type: boolean + $ref: /schemas/types.yaml#/definitions/flag + description: | + Present when HDCP2x is enabled. + + xlnx,hdcp1x-keymgmt: + description: | + A phandle to a syscon device, used to access + HDCP1x keymgmt registers. + $ref: /schemas/types.yaml#/definitions/phandle + + phys: + description: | + This denotes phandles for phy lanes registered for HDMI protocol. + + phy-names: + items: + - const: hdmi-phy0 + - const: hdmi-phy1 + - const: hdmi-phy2 + - const: hdmi-phy3 + + ports: + type: object + + properties: + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + port@0: + type: object + description: | + Sink port node with one endpoint connected to a hdmi-connector node. + properties: + reg: + const: 0 + endpoint: + type: object + properties: + remote-endpoint: true + required: + - remote-endpoint + additionalProperties: false + additionalProperties: false + + port@1: + type: object + description: | + Source port node with one endpoint. + properties: + reg: + const: 1 + endpoint: + type: object + properties: + remote-endpoint: true + required: + - remote-endpoint + additionalProperties: false + additionalProperties: false + + required: + - "#address-cells" + - "#size-cells" + - port@0 + - port@1 + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - xlnx,edid-ram-size + - xlnx,max-bits-per-component + - xlnx,max-frl-rate + - xlnx,frl-clk-freq-khz + - xlnx,vid-clk-freq-khz + - xlnx,input-pixels-per-clock + - phys + - phy-names + - ports + +additionalProperties: false + +examples: + - | + v_hdmi_rxss1: v_hdmi_rxss1@80000000 { + compatible = "xlnx,v-hdmi-rxss1-1.1"; + reg = <0x80000000 0x10000>; + clock-names = "s_axi_cpu_aclk", "frl_clk", "s_axis_video_aclk"; + clocks = <&zynqmp_clk 71>, <&misc_clk_4>, <&misc_clk_5>; + interrupt-parent = <&gic>; + interrupt-names = "hdcp14_irq", "hdcp14_timer_irq", "hdcp22_irq", "hdcp22_timer_irq", "irq"; + interrupts = <0 106 4>, <0 107 4>, <0 110 4>, <0 111 4>, <0 91 4>; + xlnx,edid-ram-size = /bits/ 16 <0x100>; + xlnx,input-pixels-per-clock = /bits/ 8 <0x8>; + xlnx,max-bits-per-component = /bits/ 8 <0xa>; + xlnx,max-frl-rate = /bits/ 8 <0x6>; + xlnx,frl-clk-freq-khz = <449955>; + xlnx,vid-clk-freq-khz = <400000>; + xlnx,include-hdcp; + xlnx,include-hdcp-1-4; + xlnx,include-hdcp-2-2; + xlnx,hdcp1x-keymgmt = <&hdcp_keymngmt_blk_1>; + phy-names = "hdmi-phy0", "hdmi-phy1", "hdmi-phy2", "hdmi-phy3"; + phys = <&hdmiphy1_lane0 0 1 1 0>, + <&hdmiphy1_lane1 0 1 1 0>, + <&hdmiphy1_lane2 0 1 1 0>, + <&hdmiphy1_lane3 0 1 1 0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + hdmi_rx_in: endpoint { + remote-endpoint = <&hdmi_connector_out>; + }; + }; + port@1 { + reg = <1>; + hdmi_rx_out: endpoint { + remote-endpoint = <&vpss_in>; + }; + }; + }; + }; + hdcp_keymngmt_blk_1: hdcp_keymngmt_blk@80040000 { + compatible = "xlnx,hdcp-keymngmt-blk-1.0", "syscon"; + reg = <0x80040000 0x10000>; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-hls.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-hls.txt @@ -0,0 +1,64 @@ +Xilinx High-Level Synthesis Core (HLS) +-------------------------------------- + +High-Level Synthesis cores are synthesized from a high-level function +description developed by the user. As such their functions vary widely, but +they all share a set of common characteristics that allow them to be described +by common bindings. + + +Required properties: + +- compatible: This property must contain "xlnx,v-hls" to indicate that the + core is compatible with the generic Xilinx HLS DT bindings. It can also + contain a more specific string to identify the HLS core implementation. The + value of those implementation-specific strings is out of scope for these DT + bindings. + +- reg: Physical base address and length of the registers sets for the device. + The HLS core has two registers sets, the first one contains the core + standard registers and the second one contains the custom user registers. + +- clocks: Reference to the video core clock. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The HLS core has one input port (0) and one output port (1). + +Required port properties: + +- xlnx,video-format: Video format as defined in video.txt. +- xlnx,video-width: Video width as defined in video.txt. + +Example: + + hls_0: hls@43c00000 { + compatible = "xlnx,v-hls-sobel", "xlnx,v-hls"; + reg = <0x43c00000 0x24>, <0x43c00024 0xa0>; + clocks = <&clkc 15>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + hls0_in: endpoint { + remote-endpoint = <&vdma_out>; + }; + }; + port@1 { + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + hls0_out: endpoint { + remote-endpoint = <&vdma_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-multi-scaler.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-multi-scaler.txt @@ -0,0 +1,95 @@ +Xilinx mem2mem Multi Video Scaler (XM2MSC) +----------------------------------------- + +Required propertie(s): +- compatible : Should be "xlnx,v-multi-scaler-v1.0" +- clocks : Input clock specifier. Refer to common clk bindings. +- interrupt-parent : Interrupt controller the interrupt is routed through +- interrupts : Should contain MultiScaler interrupt +- reset-gpios : Should contain GPIO reset phandle +- reg : Physical base address and + length of the registers set for the device. +- xlnx,max-chan : Maximum number of supported scaling channels (1 - 8) +- xlnx,max-width : Maximum number of supported column/width (64 - 3840) +- xlnx,max-height : Maximum number of supported row/height (64 - 2160) +- xlnx,dma-addr-width : dma address width (either 32 or 64) +- xlnx,pixels-per-clock : pixels per clock set in IP (1, 2 or 4) +- xlnx,vid-formats : A list of strings indicating what video memory + formats the IP has been configured to support. + See VIDEO FORMATS table below and examples. +- xlnx,num-taps : The number of filter taps for scaling (6, 8, 10, 12) + +VIDEO FORMATS +The following table describes the legal string values to be used for +the xlnx,vid-formats property. To the left is the string value and the +column to the right describes the format. + +IP FORMAT DTS String Description +-------------|----------------|--------------------- +RGB8 bgr888 Packed RGB, 8 bits per component. + Every RGB pixel in memory is represented with + 24 bits. +RGBX8 xbgr8888 Packed RGB, 8 bits per component. Every RGB + pixel in memory is represented with 32 bits. + Bits[31:24] do not contain pixel information. +BGRX8 xrgb8888 Packed BGR, 8 bits per component. Every BGR + pixel in memory is represented with 32 bits. + Bits[31:24] do not contain pixel information. +RGBX10 xbgr2101010 Packed RGB, 10 bits per component. Every RGB + pixel is represented with 32 bits. Bits[31:30] + do not contain any pixel information. +YUV8 vuy888 Packed YUV 4:4:4, 8 bits per component. Every + YUV 4:4:4 pixel in memory is represented with + 24 bits. +YUVX8 xvuy8888 Packed YUV 4:4:4, 8 bits per component. + Every YUV 4:4:4 pixel in memory is represented + with 32 bits. Bits[31:24] do not contain pixel + information. +YUYV8 yuyv Packed YUV 4:2:2, 8 bits per component. Every + two YUV 4:2:2 pixels in memory are represented + with 32 bits. +UYVY8 uyvy Packed YUV 4:2:2, 8 bits per component. + Every two YUV 4:2:2 pixels in memory are + represented with 32 bits. +YUVX10 yuvx2101010 Packed YUV 4:4:4, 10 bits per component. + Every YUV 4:4:4 pixel is represented with 32 bits. + Bits[31:30] do not contain any pixel information. +Y8 y8 Packed Luma-Only, 8 bits per component. Every + luma-only pixel in memory is represented with + 8 bits. Y8 is presented as YUV 4:4:4 on the + AXI4-Stream interface. +Y10 y10 Packed Luma-Only, 10 bits per component. Every + three luma-only pixels in memory is represented + with 32 bits. Y10 is presented as YUV 4:4:4 on + the AXI4-Stream interface. +Y_UV8 nv16 Semi-planar YUV 4:2:2 with 8 bits per component. + Y and UV stored in separate planes. +Y_UV8_420 nv12 Semi-planar YUV 4:2:0 with 8 bits per component. + Y and UV stored in separate planes. +Y_UV10 xv20 Semi-planar YUV 4:2:2 with 10 bits per component. + Every 3 pixels is represented with 32 bits. + Bits[31:30] do not contain any pixel information. + Y and UV stored in separate planes. +Y_UV10_420 xv15 Semi-planar YUV 4:2:0 with 10 bits per component. + Every 3 pixels is represented with 32 bits. + Bits[31:30] do not contain any pixel information. + Y and UV stored in separate planes. + +Example + +v_multi_scaler_0: v_multi_scaler@a0000000 {\ + clocks = <&clk 71>; + compatible = "xlnx,v-multi-scaler-v1.0"; + interrupt-names = "interrupt"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; + reg = <0x0 0xa0000000 0x0 0x10000>; + xlnx,vid-formats = "bgr888","vuy888"; + reset-gpios = <&gpio 78 1>; + xlnx,max-chan = <0x01>; + xlnx,dma-addr-width = <0x20>; + xlnx,pixels-per-clock = /bits/ 8 <2>; + xlnx,max-width = <3840>; + xlnx,max-height = <2160>; + xlnx,num-taps = <6>; +}; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-remapper.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-remapper.txt @@ -0,0 +1,61 @@ +Xilinx Video Remapper +--------------------- + +The IP core remaps input pixel components to produce an output pixel with +less, more or the same number of components as the input pixel. + +Required properties: + +- compatible: Must be "xlnx,v-remapper". + +- clocks: Reference to the video core clock. + +- xlnx,video-width: Video pixel component width, as defined in video.txt. + +- #xlnx,s-components: Number of components per pixel at the input port + (between 1 and 4 inclusive). + +- #xlnx,m-components: Number of components per pixel at the output port + (between 1 and 4 inclusive). + +- xlnx,component-maps: Remapping configuration represented as an array of + integers. The array contains one entry per output component, in the low to + high order. Each entry corresponds to the zero-based position of the + corresponding input component, or the value 4 to drive a constant value on + the output component. For example, to remap RGB to BGR use <2 1 0>, and to + remap RBG to xRGB use <1 0 2 4>. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The remapper as an input port (0) and and output port (1). + +Example: RBG to xRGB remapper + + remapper_0: remapper { + compatible = "xlnx,v-remapper"; + + clocks = <&clkc 15>; + + xlnx,video-width = <8>; + + #xlnx,s-components = <3>; + #xlnx,m-components = <4>; + xlnx,component-maps = <1 0 2 4>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + remap0_in: endpoint { + remote-endpoint = <&tpg0_out>; + }; + }; + port@1 { + reg = <1>; + remap0_out: endpoint { + remote-endpoint = <&sobel0_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-rgb2yuv.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-rgb2yuv.txt @@ -0,0 +1,54 @@ +Xilinx RGB to YUV (RGB2YUV) +--------------------------- + +Required properties: + +- compatible: Must be "xlnx,v-rgb2yuv-7.1". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the video core clock. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The rgb2yuv has an input port (0) and an output port (1). + +Required port properties: + +- xlnx,video-format: Must be RBG for the input port (0) and YUV_444 for the + output port (1). + +- xlnx,video-width: Video width as defined in video.txt + +Example: + + rgb2yuv_0: rgb2yuv@40100000 { + compatible = "xlnx,v-rgb2yuv-7.1"; + reg = <0x40100000 0x10000>; + clocks = <&clkc 15>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + rgb2yuv0_in: endpoint { + remote-endpoint = <&gamma0_out>; + }; + }; + port@1 { + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + rgb2yuv0_out: endpoint { + remote-endpoint = <&cresample0_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-scaler.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-scaler.txt @@ -0,0 +1,75 @@ +Xilinx Scaler (SCALER) +------------------------------------ + +Required properties: + +- compatible: Must be "xlnx,v-scaler-8.1". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the video core clock. + +- xlnx,num-hori-taps, xlnx,num-vert-taps: The number of horizontal and vertical + taps for scaling filter(range: 2 - 12). + +- xlnx,max-num-phases: The maximum number of phases for scaling filter + (range: 2 - 64). + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The scaler has an input port (0) and an output port (1). + +Optional properties: + +- xlnx,separate-yc-coef: When set, this boolean property specifies that + the hardware uses separate coefficients for the luma and chroma filters. + Otherwise a single set of coefficients is shared for both. + +- xlnx,separate-hv-coef: When set, this boolean property specifies that + the hardware uses separate coefficients for the horizontal and vertical + filters. Otherwise a single set of coefficients is shared for both. + +Required port properties: + +- xlnx,video-format: Must be one of RBG, YUV_422, YUV_422 or YUV_420 for + both input port (0) and output port (1). The two formats must be identical. + +- xlnx,video-width: Video width as defined in video.txt + +Example: + + scaler_0: scaler@43c30000 { + compatible = "xlnx,v-scaler-8.1"; + reg = <0x43c30000 0x10000>; + clocks = <&clkc 15>; + + xlnx,num-hori-taps = <12>; + xlnx,num-vert-taps = <12>; + xlnx,max-num-phases = <4>; + xlnx,separate-hv-coef; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + scaler0_in: endpoint { + remote-endpoint = <&cresample0_out>; + }; + }; + port@1 { + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + scaler0_out: endpoint { + remote-endpoint = <&vcap0_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-scd.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-scd.txt @@ -0,0 +1,164 @@ +Xilinx Scene Change Detection IP (SCD) +-------------------------------------- + +The Xilinx Scene Change Detection IP contains two blocks: one IP block is used +for reading video frame data from memory to the device and the other IP block +is used for determining whether there is a scene change between current and the +previous frame. The IP supports YUV planar and semi-planar formats. IP only +needs luma frame to determine the scene change event. The IP supports memory +based model, which means that it will accept a dma buffer address and perform +MEM2DEV transfer followed by statistical based image processing and give the +data back to application if scene change detection is present or not. + +Another version of scene change detection IP which supports streaming model, +which means that IP can be inserted in a capture pipeline. For example, +"hdmirx -> streaming-scd -> fb_wr" is a typical capture pipeline where +streaming SCD can be embedded. The IP accespts the AXI video data and perform +histogram based statistical analysis to detect scene change. The IP supports +single channel. + +Required properties: + +- compatible: Should be "xlnx,v-scd" + +- reg: Physical base address and length of the registers set for the device + +- clocks: Reference to the video core clock. + +- reset-gpios: Specifier for a GPIO that assert SCD (AP_RST_N) reset. + +- xlnx,memory-based: This is to differentiate between memory based and + streaming based IP. The value is 1 for memory based and 0 for streaming + based IPs. + +- xlnx,numstreams: Maximum active streams IP can support is 8 and this is based + on the design. + +- xlnx,addrwidth: Size of dma address pointer in IP (either 32 or 64) + +- subdev: Each channel will have its own subdev node. Each subdev will have its + sink port. + +- port: Video port, using the DT bindings defined in ../video-interfaces.txt. + +Example: + +1. Memory based device tree + +The following example shows how the device tree would look like for a memory +based design where 8 streams are enabled. + + scd: scenechange@a0100000 { + compatible = "xlnx,v-scd"; + reg = <0x0 0xa0100000 0x0 0x1fff>; + clocks = <&misc_clk_0>; + interrupt-parent = <&gic>; + interrupts = <0 90 4>; + reset-gpios = <&gpio 94 1>; + + xlnx,memory-based; + xlnx,numstreams = <8>; + xlnx,addrwidth = <0x20>; + + #address-cells = <1>; + #size-cells = <0>; + #dma-cells = <1>; + + subdev@0 { + port@0 { + reg = <0>; + scd_in0: endpoint { + remote-endpoint = <&vcap0_out0>; + }; + }; + }; + subdev@1 { + port@0 { + reg = <0>; + scd_in1: endpoint { + remote-endpoint = <&vcap0_out1>; + }; + }; + }; + subdev@2 { + port@0 { + reg = <0>; + scd_in2: endpoint { + remote-endpoint = <&vcap0_out2>; + }; + }; + }; + subdev@3 { + port@0 { + reg = <0>; + scd_in3: endpoint { + remote-endpoint = <&vcap0_out3>; + }; + }; + }; + subdev@4 { + port@0 { + reg = <0>; + scd_in4: endpoint { + remote-endpoint = <&vcap0_out4>; + }; + }; + }; + subdev@5 { + port@0 { + reg = <0>; + scd_in5: endpoint { + remote-endpoint = <&vcap0_out5>; + }; + }; + }; + subdev@6 { + port@0 { + reg = <0>; + scd_in6: endpoint { + remote-endpoint = <&vcap0_out6>; + }; + }; + }; + subdev@7 { + port@0 { + reg = <0>; + scd_in7: endpoint { + remote-endpoint = <&vcap0_out7>; + }; + }; + }; + }; + +2. Streaming based device tree + +The following example shows how the device tree would look like for a streaming +based design. + + scd: scenechange@a0280000 { + compatible = "xlnx,v-scd"; + reg = <0x0 0xa0280000 0x0 0x1fff>; + clocks = <&clk 72>; + interrupt-parent = <&gic>; + interrupts = <0 111 4>; + reset-gpios = <&gpio 100 1>; + #address-cells = <1>; + #size-cells = <0>; + xlnx,numstreams = <1>; + + scd { + port@0 { + reg = <0x0>; + scd_in0: endpoint { + remote-endpoint = <&vpss_scaler_out>; + }; + }; + + port@1 { + reg = <0x1>; + scd_out0: endpoint { + remote-endpoint = <&vcap_hdmi_in_1>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-switch.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-switch.txt @@ -0,0 +1,55 @@ +Xilinx Video Switch +------------------- + +Required properties: + + - compatible: Must be "xlnx,v-switch-1.0". + + - reg: Physical base address and length of the registers set for the device. + + - clocks: Reference to the video core clock. + + - #xlnx,inputs: Number of input ports + - #xlnx,outputs: Number of outputs ports + + - ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + +Example: + + switch: switch@43c10000 { + compatible = "xlnx,v-switch-1.0"; + reg = <0x43c10000 0x10000>; + clocks = <&clkc 15>; + + #xlnx,inputs = <2>; + #xlnx,outputs = <2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + switch_in0: endpoint { + remote-endpoint = <&tpg_out>; + }; + }; + port@1 { + reg = <1>; + switch_in1: endpoint { + remote-endpoint = <&cresample0_out>; + }; + }; + port@2 { + reg = <2>; + switch_out0: endpoint { + remote-endpoint = <&scaler0_in>; + }; + }; + port@3 { + reg = <3>; + switch_out1: endpoint { + remote-endpoint = <&vcap0_in1>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt @@ -6,7 +6,8 @@ - compatible: Must contain at least one of "xlnx,v-tpg-5.0" (TPG version 5.0) - "xlnx,v-tpg-6.0" (TPG version 6.0) + "xlnx,v-tpg-7.0" (TPG version 7.0) + "xlnx,v-tpg-8.0" (TPG version 8.0) TPG versions backward-compatible with previous versions should list all compatible versions in the newer to older order. @@ -23,6 +24,8 @@ Optional properties: +- xlnx,ppc: Pixels per clock. Valid values are 1, 2, 4 or 8. + - xlnx,vtc: A phandle referencing the Video Timing Controller that generates video timings for the TPG test patterns. @@ -30,16 +33,26 @@ input. The GPIO active level corresponds to the selection of VTC-generated video timings. +- reset-gpios: Specifier for a GPIO that assert TPG (AP_RST_N) reset. + This property is mandatory for TPG v7.0 and above. + +- xlnx,max-height: Maximum number of lines. + This property is mandatory for TPG v8.0. Value ranges from 64 to 7760. + +- xlnx,max-width: Maximum number of pixels in a line. + This property is mandatory for TPG v8.0. Value ranges from 64 to 10328. + The xlnx,vtc and timing-gpios properties are mandatory when the TPG is synthesized with two ports and forbidden when synthesized with one port. Example: tpg_0: tpg@40050000 { - compatible = "xlnx,v-tpg-6.0", "xlnx,v-tpg-5.0"; + compatible = "xlnx,v-tpg-5.0"; reg = <0x40050000 0x10000>; clocks = <&clkc 15>; + xlnx,ppc = <2>; xlnx,vtc = <&vtc_3>; timing-gpios = <&ps7_gpio_0 55 GPIO_ACTIVE_LOW>; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-vpss-csc.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-vpss-csc.txt @@ -0,0 +1,67 @@ +Xilinx VPSS Color Space Converter (CSC) +----------------------------------------- +The Xilinx VPSS Color Space Converter (CSC) is a Video IP that supports +color space conversion from RGB or YUV(444, 422, 420)input to RGB or +YUV(444, 422, 420) output. + +Required properties: + +- compatible: Must be "xlnx,v-vpss-csc". + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the clock that drives the ap_clk signal. + +- xlnx,max-height: Maximum number of lines. + Valid range from 64 to 4320. + +- xlnx,max-width: Maximum number of pixels in a line. + Valid range from 64 to 8192. + +- reset-gpios: Specifier for a GPIO that assert VPSS CSC (AP_RST_N) reset. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The scaler has an input port (0) and an output port (1). + +Required port properties: + +- xlnx,video-format: Must be XVIP_VF_RBG, XVIP_VF_YUV_444 or XVIP_VF_YUV_422 + for input port (0) and XVIP_VF_RBG, XVIP_VF_YUV_444 or XVIP_VF_YUV_422 + for output port (1). See for more details. + +- xlnx,video-width: Video width as defined in video.txt. Must be either 8 or 10. + +Example: + csc_1:csc@a0040000 { + compatible = "xlnx,v-vpss-csc"; + reg = <0x0 0xa0040000 0x0 0x10000>; + clocks = <&vid_stream_clk>; + reset-gpios = <&gpio 84 1>; + xlnx,max-width = <3840>; + xlnx,max-height = <2160>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + /* Sink Pad */ + port@0 { + reg = <0>; + xlnx,video-format = ; + xlnx,video-width = <8>; + + csc_in: endpoint { + remote-endpoint = <&gamma_out>; + }; + }; + /* Source Pad */ + port@1 { + reg = <1>; + xlnx,video-format = ; + xlnx,video-width = <8>; + + csc_out: endpoint { + remote-endpoint = <&scalar_in>; + }; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,v-vpss-scaler.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,v-vpss-scaler.txt @@ -0,0 +1,93 @@ + Xilinx VPSS Scaler +------------------------ + +Required properties: + +- compatible: Must be "xlnx,v-vpss-scaler-2.2" or "xlnx,v-vpss-scaler-1.0". + The older string "xlnx,v-vpss-scaler" will be deprecated. + +- reg: Physical base address and length of the registers set for the device. + +- clocks: Reference to the AXI Streaming clock feeding the VPSS Scaler AP_CLK + and AXI4 Lite control interface clock. + +- clock-names: Must contain "aclk_axis" and "aclk_ctrl" in the same order as + clocks listed in clocks property. + +- xlnx,num-hori-taps, xlnx,num-vert-taps: The number of horizontal and vertical + taps for scaling filter(range: 2,4,6,8,10,12). + + A value of 2 represents bilinear filters. A value of 4 represents bicubic. + Values 6,8,10,12 represent polyphase filters. + +- xlnx,pix-per-clk : The pixels per clock property of the IP + +- reset-gpios: Specifier for a GPIO that assert for VPSS Scaler reset. + This property is mandatory for the Scaler + +- xlnx,max-height: Maximum number of lines. + Valid range from 64 to 4320. + +- xlnx,max-width: Maximum number of pixels in a line. + Valid range from 64 to 8192. + +- ports: Video ports, using the DT bindings defined in ../video-interfaces.txt. + The scaler has an input port (0) and an output port (1). + +Required port properties: + +- xlnx,video-format: Must be one of XVIP_VF_RBG or XVIP_VF_YUV_422 for + input port (0) and must be XVIP_VF_RBG or XVIP_VF_YUV_422 or for + the output port (1). + See for more details. + +- reg: This value represents the media pad of the V4L2 sub-device. + A Sink Pad is represented by reg = <0> + A Source Pad is represented by reg = <1> + +- xlnx,video-width: Video width as defined in video.txt + +Example: + + scaler_1:scaler@a0000000 { + compatible = "xlnx,v-vpss-scaler-1.0"; + reg = <0x0 0xa0000000 0x0 0x40000>; + clocks = <&vid_stream_clk>, <&misc_clk_2>; + clock-names = "aclk_axis", "aclk_ctrl"; + xlnx,num-hori-taps = <8>; + xlnx,num-vert-taps = <8>; + xlnx,pix-per-clk = <2>; + reset-gpios = <&gpio 87 1>; + xlnx,max-width = <3840>; + xlnx,max-height = <2160>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + /* Sink Pad */ + reg = <0>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + scaler_in: endpoint { + remote-endpoint = <&csc_out>; + }; + }; + + port@1 { + /* Source Pad */ + reg = <1>; + + xlnx,video-format = ; + xlnx,video-width = <8>; + + scaler_out: endpoint { + remote-endpoint = <&vcap_tpg_in>; + }; + }; + }; + + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/media/xilinx/xlnx,video.txt @@ -21,6 +21,18 @@ - ports: Video port, using the DT bindings defined in ../video-interfaces.txt. +Optional properties: +- memory-region : phandle to /reserved-memory node. + If memory is reserved for special use by DMAs then this node + can be used to refer and use from this reserved memory region. + +- xlnx,atomic_streamon: This property is useful for the scenario where some of + the upstream entities are being shared with multiple video devices (dma + engines) in the same media pipeline. When set, all entities belonging to + the media pipeline will get enabled even when any one of the dma engine + present in the media pipeline start streaming, otherwise the entities + get enabled only when all dma engines start streaming. + Required port properties: - direction: should be either "input" or "output" depending on the direction @@ -53,3 +65,46 @@ }; }; }; + +Example using reserved memory: +Reserving from 32bit Shared CMA pool of 512MiB using System RAM: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/ { + reserved-memory { + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + psmem_multimedia: multimedia_cma_mem_region { + compatible = "shared-dma-pool"; + reg = <0x00 0x40000000 0x00 0x20000000>; + reusable; + }; + }; +}; +... + video_cap { + /* ... */ + memory-region = <&psmem_multimedia>; + }; + + +Reserving from 64bit Shared DMA pool of 1792 MiB using external PL based +DDR memory: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +/ { + reserved-memory { + #address-cells = <0x2>; + #size-cells = <0x2>; + ranges; + plmem_multimedia: multimedia_dma_mem_region { + compatible = "shared-dma-pool"; + no-map; + reg = <0x48 0x0 0x0 0x70000000>; + }; + }; +}; +... + video_cap { + /* ... */ + memory-region = <&plmem_multimedia>; + } --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/mfd/syscon.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -73,6 +73,8 @@ - rockchip,rv1126-qos - starfive,jh7100-sysmain - ti,am654-dss-oldi-io-ctrl + - xlnx,zynqmp-dpaud-setting + - xlnx,hdcp-keymngmt-blk-1.0 - const: syscon --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/misc/xlnx,dpu.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/misc/xlnx,dpu.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/misc/xlnx,dpu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Deep learning Processing Unit (DPU) Vivado Flow + +maintainers: + - Ye Yang + +description: |+ + The DPUCZDX8G is the deep learning processing unit (DPU) designed to + support the Zynq UltraScale+ MPSoC and MicroBlaze. It is a configurable + computation engine optimized for convolutional neural networks. + + The driver supports up to 4 DPU cores with 40-bit addressing and 1 + softmax core with 32-bit addressing, depending on how the user config + the IP in Vivado TRD Flow. + + For more details refer to PG338 "DPUCZDX8G for Zynq UltraScale+ MPSoCs" + (https://www.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/dpu/v3_4/pg338-dpu.pdf) + +properties: + compatible: + enum: + - xlnx,dpuczdx8g-3.4 + - xlnx,dpuczdx8g-4.0 + - xlnx,dpuczdx8g-4.1 + + reg: + maxItems: 1 + + clocks: + description: List of clock specifiers. + items: + - description: AXI Lite clock + - description: dsp clock, used for DSP blocks in the DPUCZDX8G. The frequency is twice that of dpu clock + - description: dpu clock, used for DPUCZDX8G general logic + + clock-names: + items: + - const: s_axi_aclk + - const: dpu_2x_clk + - const: m_axi_dpu_aclk + + interrupts: + description: One interrupt per available DPU core(up to 4) or 1 softmax core + minItems: 1 + maxItems: 5 + + interrupt-names: + minItems: 1 + maxItems: 5 + items: + pattern: "^(dpu[0-3]|sfm)_interrupt$" + +required: + - compatible + - reg + - interrupts + - interrupt-names + +additionalProperties: false + +examples: + # Example for ZynqMP (2 DPU and 1 SOFTMAX) + - | + #include + + dpuczdx8g@8f000000 { + compatible = "xlnx,dpuczdx8g-3.4"; + reg = <0x8f000000 0x1000000>; + interrupt-parent = <&gic>; + interrupts = , + , + ; + interrupt-names = "dpu0_interrupt", "dpu1_interrupt", "sfm_interrupt"; + clocks = <&zynqmp_clk 71>, <&misc_clk_0>, <&misc_clk_1>; + clock-names = "s_axi_aclk", "dpu_2x_clk", "m_axi_dpu_aclk"; + }; + + # Example for Microblaze (1 DPU) + - | + dpuczdx8g@1000000 { + compatible = "xlnx,dpuczdx8g-3.4"; + reg = <0x01000000 0x1000000>; + interrupt-parent = <µblaze_0_axi_intc>; + interrupts = <8 2>; + interrupt-names = "dpu0_interrupt"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/misc/xlnx,sd-fec.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/misc/xlnx,sd-fec.yaml @@ -0,0 +1,140 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/misc/xlnx,sd-fec.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx SDFEC(16nm) IP + +maintainers: + - Cvetic, Dragan + - Erim, Salih + +description: + The Soft Decision Forward Error Correction (SDFEC) Engine is a Hard IP block + which provides high-throughput LDPC and Turbo Code implementations. + The LDPC decode & encode functionality is capable of covering a range of + customer specified Quasi-cyclic (QC) codes. The Turbo decode functionality + principally covers codes used by LTE. The FEC Engine offers significant + power and area savings versus implementations done in the FPGA fabric. + +properties: + compatible: + const: xlnx,sd-fec-1.1 + + reg: + maxItems: 1 + + clocks: + minItems: 2 + maxItems: 8 + additionalItems: true + items: + - description: Main processing clock for processing core + - description: AXI4-Lite memory-mapped slave interface clock + - description: Control input AXI4-Stream Slave interface clock + - description: DIN AXI4-Stream Slave interface clock + - description: Status output AXI4-Stream Master interface clock + - description: DOUT AXI4-Stream Master interface clock + - description: DIN_WORDS AXI4-Stream Slave interface clock + - description: DOUT_WORDS AXI4-Stream Master interface clock + + clock-names: + allOf: + - minItems: 2 + maxItems: 8 + additionalItems: true + items: + - const: core_clk + - const: s_axi_aclk + - items: + enum: + - core_clk + - s_axi_aclk + - s_axis_ctrl_aclk + - s_axis_din_aclk + - m_axis_status_aclk + - m_axis_dout_aclk + - s_axis_din_words_aclk + - m_axis_dout_words_aclk + + interrupts: + maxItems: 1 + + xlnx,sdfec-code: + description: + The SD-FEC integrated block supports Low Density Parity Check (LDPC) + decoding and encoding and Turbo code decoding. The LDPC codes used are + highly configurable, and the specific code used can be specified on + a codeword-by-codeword basis. The Turbo code decoding is required by LTE + standard. + $ref: /schemas/types.yaml#/definitions/string + items: + enum: [ ldpc, turbo ] + + xlnx,sdfec-din-width: + description: + Configures the DIN AXI stream where a value of 1 + configures a width of "1x128b", 2 a width of "2x128b" and 4 configures a width + of "4x128b". + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 1, 2, 4 ] + + xlnx,sdfec-din-words: + description: + A value 0 indicates that the DIN_WORDS interface is + driven with a fixed value and is not present on the device, a value of 1 + configures the DIN_WORDS to be block based, while a value of 2 configures the + DIN_WORDS input to be supplied for each AXI transaction. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2 ] + + xlnx,sdfec-dout-width: + description: + Configures the DOUT AXI stream where a value of 1 configures a width of "1x128b", + 2 a width of "2x128b" and 4 configures a width of "4x128b". + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 1, 2, 4 ] + + xlnx,sdfec-dout-words: + description: + A value 0 indicates that the DOUT_WORDS interface is + driven with a fixed value and is not present on the device, a value of 1 + configures the DOUT_WORDS to be block based, while a value of 2 configures the + DOUT_WORDS input to be supplied for each AXI transaction. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2 ] + +required: + - compatible + - reg + - clocks + - clock-names + - xlnx,sdfec-code + - xlnx,sdfec-din-width + - xlnx,sdfec-din-words + - xlnx,sdfec-dout-width + - xlnx,sdfec-dout-words + +additionalProperties: false + +examples: + - | + #include + + sd-fec@a0040000 { + compatible = "xlnx,sd-fec-1.1"; + reg = <0xa0040000 0x40000>; + clocks = <&misc_clk_2>, <&misc_clk_0>, <&misc_clk_1>, <&misc_clk_1>, + <&misc_clk_1>, <&misc_clk_1>; + clock-names = "core_clk", "s_axi_aclk", "s_axis_ctrl_aclk", + "s_axis_din_aclk", "m_axis_status_aclk", + "m_axis_dout_aclk"; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + xlnx,sdfec-code = "ldpc"; + xlnx,sdfec-din-width = <2>; + xlnx,sdfec-din-words = <0>; + xlnx,sdfec-dout-width = <1>; + xlnx,sdfec-dout-words = <0>; + }; + --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/net/can/xilinx,can.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/net/can/xilinx,can.yaml @@ -5,7 +5,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: - Xilinx Axi CAN/Zynq CANPS controller + Xilinx CAN and CANFD controller maintainers: - Appana Durga Kedareswara rao @@ -49,6 +49,10 @@ resets: maxItems: 1 + xlnx,has-ecc: + $ref: /schemas/types.yaml#/definitions/flag + description: CAN TX_OL, TX_TL and RX FIFOs have ECC support(AXI CAN) + required: - compatible - reg @@ -137,6 +141,7 @@ interrupts = ; tx-fifo-depth = <0x40>; rx-fifo-depth = <0x40>; + xlnx,has-ecc; }; - | --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/net/mediatek,net.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/net/mediatek,net.yaml @@ -337,8 +337,8 @@ minItems: 4 clocks: - minItems: 34 - maxItems: 34 + minItems: 24 + maxItems: 24 clock-names: items: @@ -351,18 +351,6 @@ - const: ethwarp_wocpu1 - const: ethwarp_wocpu0 - const: esw - - const: netsys0 - - const: netsys1 - - const: sgmii_tx250m - - const: sgmii_rx250m - - const: sgmii2_tx250m - - const: sgmii2_rx250m - - const: top_usxgmii0_sel - - const: top_usxgmii1_sel - - const: top_sgm0_sel - - const: top_sgm1_sel - - const: top_xfi_phy0_xtal_sel - - const: top_xfi_phy1_xtal_sel - const: top_eth_gmii_sel - const: top_eth_refck_50m_sel - const: top_eth_sys_200m_sel @@ -375,16 +363,10 @@ - const: top_netsys_sync_250m_sel - const: top_netsys_ppefb_250m_sel - const: top_netsys_warp_sel - - const: wocpu1 - - const: wocpu0 - const: xgp1 - const: xgp2 - const: xgp3 - mediatek,sgmiisys: - minItems: 2 - maxItems: 2 - patternProperties: "^mac@[0-1]$": type: object --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/net/xilinx-phy.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/net/xilinx-phy.txt @@ -0,0 +1,15 @@ +Xilinx PCS/PMA PHY bindings + +Required properties: + - reg - The ID number for the phy, usually a small integer + +Optional properties: + - xlnx,phy-type - Describes type 1000BaseX (set to 0x5) or + SGMII (set to 0x4) + +Example: + + ethernet-phy@9 { + reg = <9>; + xlnx,phy-type = <0x5>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml @@ -4,29 +4,69 @@ $id: http://devicetree.org/schemas/net/xlnx,axi-ethernet.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: AXI 1G/2.5G Ethernet Subsystem +title: XILINX AXI Ethernet Subsystem description: | - Also called AXI 1G/2.5G Ethernet Subsystem, the xilinx axi ethernet IP core - provides connectivity to an external ethernet PHY supporting different - interfaces: MII, GMII, RGMII, SGMII, 1000BaseX. It also includes two - segments of memory for buffering TX and RX, as well as the capability of - offloading TX/RX checksum calculation off the processor. + Following MAC configurations are supported- + a) AXI 1G/2.5G Ethernet Subsystem. + b) 10G/25G High Speed Ethernet Subsystem. + c) 10 Gigabit Ethernet Subsystem. + d) USXGMII Ethernet Subsystem. + e) MRMAC Ethernet Subsystem. + f) 1G/10G/25G Switching Ethernet Subsystem. + g) DCMAC Ethernet Subsystem. + + AXI 1G/2.5G Ethernet Subsystem- also called AXI 1G/2.5G Ethernet Subsystem, + the xilinx axi ethernet IP core provides connectivity to an external ethernet + PHY supporting different interfaces: MII, GMII, RGMII, SGMII, 1000BaseX. + It also includes two segments of memory for buffering TX and RX, as well as + the capability of offloading TX/RX checksum calculation off the processor. Management configuration is done through the AXI interface, while payload is sent and received through means of an AXI DMA controller. This driver includes the DMA driver code, so this driver is incompatible with AXI DMA driver. + 10G/25G High Speed Ethernet Subsystem implements the 25G Ethernet Media + Access Controller (MAC) with a Physical Coding Sublayer (PCS) as specified + by the 25G Ethernet Consortium. Legacy operation at 10 Gb/s is supported. + + The 10G Ethernet subsystem provides 10 Gb/s Ethernet MAC, Physical Coding + Sublayer (PCS) and Physical Medium Attachment (PMA) transmit and receive + functionality over an AXI4-Stream interface. + + The Universal Serial 10GE Media Independent Interface (USXGMII) ethernet + subsystem implements an Ethernet Media Access Controller (MAC) with a + mechanism to carry a single port of 10M, 100M, 1G, 2.5G, 5G or 10GE over an + IEEE 802.3 Clause 49 BASE-R physical coding sublayer/physical layer (PCS/PHY). + + MRMAC is a hardened Ethernet IP on Versal supporting multiple rates from + 10G to 100G which can be used with a soft DMA controller. + + The Xilinx 1G/10G/25G Switching Ethernet Subsystem contains integrated MAC + and PCS and it supports runtime switchable speeds among 1G,10G & 25G + + 600G Channelized Multirate Ethernet Subsystem (DCMAC Subsystem) is hardened + Ethernet IP that can be configured for up to six ports with independent MAC + and PHY functions at the IEEE Standard MAC Rates from 100GE to 400GE + and an overall maximum bandwidth of 600 Gbps. + maintainers: - Radhey Shyam Pandey properties: compatible: enum: - - xlnx,axi-ethernet-1.00.a - - xlnx,axi-ethernet-1.01.a - - xlnx,axi-ethernet-2.01.a + - xlnx,axi-ethernet-1.00.a # AXI 1G Ethernet Subsystem. + - xlnx,axi-ethernet-1.01.a # AXI 1G Ethernet Subsystem. + - xlnx,axi-ethernet-2.01.a # AXI 1G Ethernet Subsystem. + - xlnx,axi-2_5-gig-ethernet-1.0 # AXI 2.5G Ethernet Subsystem. + - xlnx,ten-gig-eth-mac # 10 Gigabit Ethernet Subsystem. + - xlnx,xxv-ethernet-1.0 # 10G/25G High Speed Ethernet Subsystem. + - xlnx,xxv-usxgmii-ethernet-1.0 # USXGMII Ethernet Subsystem. + - xlnx,mrmac-ethernet-1.0 # MRMAC Ethernet Subsystem. + - xlnx,ethernet-1-10-25g-2.7 # 1G/10G/25G Switching Ethernet Subsystem. + - xlnx,dcmac-2.4 # DCMAC Ethernet Subsystem. reg: description: @@ -34,7 +74,9 @@ and length of the AXI DMA controller IO space, unless axistream-connected is specified, in which case the reg attribute of the node referenced by it is used. - maxItems: 2 + Address and length of Ethernet Offload Engine IO space. + minItems: 1 + maxItems: 3 interrupts: items: @@ -87,8 +129,9 @@ xlnx,switch-x-sgmii: type: boolean description: - Indicate the Ethernet core is configured to support both 1000BaseX and - SGMII modes. If set, the phy-mode should be set to match the mode + Indicate that Ethernet core supports either 1000BaseX <-> SGMII modes + switching in 1G MAC or 2500BaseX <-> SGMII modes switching for + AXI 2.5G MAC. If set, the phy-mode should be set to match the mode selected on core reset (i.e. by the basex_or_sgmii core input line). clocks: @@ -136,19 +179,235 @@ minItems: 2 maxItems: 32 + dma-coherent: true + + xlnx,eth-hasnobuf: + type: boolean + description: Used when 1G MAC is configured in non-processor mode. + + xlnx,usxgmii-rate: + $ref: /schemas/types.yaml#/definitions/uint32 + description: USXGMII PHY speed + + xlnx,rxtsfifo: + $ref: /schemas/types.yaml#/definitions/phandle + description: Configures the axi fifo for receive timestamping. + + axififo-connected: + $ref: /schemas/types.yaml#/definitions/phandle + description: Configures the axi fifo for transmit timestamping. + + ptp-hardware-clock: + $ref: /schemas/types.yaml#/definitions/phandle + description: Indicate the xilinx PTP device node to read PTP clock + index(/dev/ptp0 etc). This property is for MRMAC and 10G/25G. + + xlnx,mrmac-rate: + $ref: /schemas/types.yaml#/definitions/uint32 + description: MRMAC rate in Mbps. + deprecated: true + + xlnx,gtlane: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Indicate the GT reset and speed control lane for the + the current MRMAC lane. + + xlnx,gtpll: + $ref: /schemas/types.yaml#/definitions/phandle + description: Handle to AXI GPIO instance for GT PLL mask control. + This is required to control the common PLL mask bits. + + xlnx,gtctrl: + $ref: /schemas/types.yaml#/definitions/phandle + description: Handle to AXI GPIO instance for GT speed and reset + control for each MRMAC lane. + + xlnx,phcindex: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Indicate the index of the physical hardware clock + to be used as per PTP clock connected to the given + MRMAC lane. + deprecated: true + + xlnx,runtime-switch: + $ref: /schemas/types.yaml#/definitions/string + description: Indicates speed switching capability of 1G/10G/25G + ethernet IP. Can be either "1G / 10G", which is the default switching + capability if this property is not present or "1G / 10G / 25G". + + max-speed: true + + gt_ctrl-gpios: + description: Phandle and specifier for GT control GPIO used to + configure GT. + + gt_rx_dpath-gpios: + description: Phandle and specifier for the GPIO used to + reset GT Rx datapath. + + gt_tx_dpath-gpios: + description: Phandle and specifier for the GPIO used to + reset GT Tx datapath. + + gt_tx_rst_done-gpios: + description: Phandle and specifier for the GPIO used to + get GT Tx reset status. + + gt_rx_rst_done-gpios: + description: Phandle and specifier for the GPIO used to + get GT Rx reset status. + + gt_rsts-gpios: + description: Phandle and specifier for the GPIO used to + reset Tx and Rx serdes. + + reg-names: + oneOf: + - items: + - const: mac + - const: dma + - const: eoe + - items: + - enum: + - mac + - enum: + - dma + - eoe + - items: + - const: mac + + xlnx,has-hw-offload: + type: boolean + description: Used when Ethernet Offload is connected to existing Ethernet IP. + + xlnx,tx-hw-offload: + description: + Segmentation offload. 0 for disabling segmentation offload, + 1 for checksum offload and 2 for both checksum and UDP segmentation offload. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + + xlnx,rx-hw-offload: + description: + Receive offload. 0 for disabling receive offload, + 1 for checksum offload and 2 for both checksum and UDP receive offload. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + required: - compatible - interrupts - reg - xlnx,rxmem - - phy-handle allOf: - $ref: /schemas/net/ethernet-controller.yaml# + - if: + properties: + compatible: + contains: + enum: + - xlnx,xxv-usxgmii-ethernet-1.0 + + then: + properties: + xlnx,usxgmii-rate: + enum: [10, 100, 1000, 2500, 5000, 10000] + + - if: + properties: + compatible: + contains: + enum: + - xlnx,mrmac-ethernet-1.0 + + then: + properties: + max-speed: + enum: [10000, 25000] + + xlnx,gtlane: + enum: [0, 1, 2, 3] + + xlnx,phcindex: + enum: [0, 1, 2, 3] + + required: + - max-speed + - xlnx,gtlane + - xlnx,gtpll + - xlnx,gtctrl + + - if: + properties: + compatible: + contains: + enum: + - xlnx,ethernet-1-10-25g-2.7 + + then: + properties: + xlnx,runtime-switch: + enum: + - 1G / 10G + - 1G / 10G / 25G + + - if: + properties: + compatible: + contains: + enum: + - xlnx,axi-ethernet-1.00.a + - xlnx,axi-ethernet-1.01.a + - xlnx,axi-ethernet-2.01.a + - xlnx,axi-2_5-gig-ethernet-1.0 + then: + required: + - phy-handle + + - if: + properties: + compatible: + contains: + enum: + - xlnx,dcmac-2.4 + then: + properties: + max-speed: + enum: [100000, 200000, 400000] + + gt_ctrl-gpios: + maxItems: 32 + + gt_rx_dpath-gpios: + maxItems: 23 + + gt_tx_dpath-gpios: + maxItems: 23 + + gt_tx_rst_done-gpios: + maxItems: 24 + + gt_rx_rst_done-gpios: + maxItems: 24 + + gt_rsts-gpios: + maxItems: 14 + + required: + - max-speed + - gt_ctrl-gpios + - gt_rx_dpath-gpios + - gt_tx_dpath-gpios + - gt_tx_rst_done-gpios + - gt_rx_rst_done-gpios + - gt_rsts-gpios + additionalProperties: false examples: +# 1) AXI 1G/2.5G Ethernet Subsystem + AXIDMA without "axistream-connected" property - | axi_ethernet_eth: ethernet@40c00000 { compatible = "xlnx,axi-ethernet-1.00.a"; @@ -174,6 +433,7 @@ }; }; +# 2) AXI 1G/2.5G Ethernet Subsystem + AXIDMA with "axistream-connected" property - | axi_ethernet_eth1: ethernet@40000000 { compatible = "xlnx,axi-ethernet-1.00.a"; @@ -181,7 +441,7 @@ clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk"; clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>; phy-mode = "mii"; - reg = <0x00 0x40000000 0x00 0x40000>; + reg = <0x40000000 0x40000>; xlnx,rxcsum = <0x2>; xlnx,rxmem = <0x800>; xlnx,txcsum = <0x2>; @@ -195,5 +455,121 @@ device_type = "ethernet-phy"; reg = <1>; }; + }; + }; + +# 3) #Example for MRMAC Ethernet subsystem + - | + gt_pll: gpio@a4000000 { + reg = <0xa4000000 0x10000>; + + }; + + gt_ctrl: gpio@a4010000 { + reg = <0xa4010000 0x40000>; + + }; + + mrmac: ethernet@80000000 { + axistream-connected = <&dma>; + compatible = "xlnx,mrmac-ethernet-1.0"; + reg = <0xa4090000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 91 4>; + max-speed = <10000>; + xlnx,gtpll = <>_pll>; + xlnx,gtctrl = <>_ctrl>; + xlnx,gtlane = <0x0>; + xlnx,rxmem = <0x8000>; + ptp-hardware-clock = <&ptp_device>; + + }; + +# 4) #Example for DCMAC Ethernet subsystem + - | + gpio1: gpio@a4130000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0xa4130000 0x10000>; + #gpio-cells = <0x2>; + gpio-controller; + }; + + gpio2: gpio@a4150000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0xa4150000 0x10000>; + #gpio-cells = <0x2>; + gpio-controller; + }; + + gpio3: gpio@a4140000 { + compatible = "xlnx,xps-gpio-1.00.a"; + reg = <0xa4140000 0x10000>; + #gpio-cells = <0x2>; + gpio-controller; + }; + + dcmac: ethernet@a4000000 { + axistream-connected = <&dma>; + compatible = "xlnx,dcmac-2.4"; + reg = <0xa4000000 0x100000>; + interrupt-parent = <&gic>; + interrupts = <0x0 0x5c 0x4 0x0 0x5d 0x4>; + xlnx,rxmem = <0x8000>; + max-speed = <100000>; + + gt_ctrl-gpios = <&gpio1 0 0>, <&gpio1 1 0>, <&gpio1 2 0>, <&gpio1 3 0>, <&gpio1 4 0>, <&gpio1 5 0>, + <&gpio1 6 0>, <&gpio1 7 0>, <&gpio1 8 0>, <&gpio1 9 0>, <&gpio1 10 0>, <&gpio1 11 0>, <&gpio1 12 0>, + <&gpio1 13 0>, <&gpio1 14 0>, <&gpio1 15 0>, <&gpio1 16 0>, <&gpio1 17 0>, <&gpio1 18 0>, + <&gpio1 19 0>, <&gpio1 20 0>, <&gpio1 21 0>, <&gpio1 22 0>, <&gpio1 23 0>, <&gpio1 24 0>, + <&gpio1 25 0>, <&gpio1 26 0>, <&gpio1 27 0>, <&gpio1 28 0>, <&gpio1 29 0>, <&gpio1 30 0>, + <&gpio1 31 0>; + + gt_rx_dpath-gpios = <&gpio2 0 0>, <&gpio2 1 0>, <&gpio2 2 0>, <&gpio2 3 0>, <&gpio2 4 0>, + <&gpio2 5 0>, <&gpio2 6 0>, <&gpio2 7 0>, <&gpio2 8 0>, <&gpio2 9 0>, <&gpio2 10 0>, <&gpio2 11 0>, + <&gpio2 12 0>, <&gpio2 13 0>, <&gpio2 14 0>, <&gpio2 15 0>, <&gpio2 16 0>, <&gpio2 17 0>, + <&gpio2 18 0>, <&gpio2 19 0>, <&gpio2 20 0>, <&gpio2 21 0>, <&gpio2 22 0>; + + gt_tx_dpath-gpios = <&gpio2 0 0>, <&gpio2 1 0>, <&gpio2 2 0>, <&gpio2 3 0>, <&gpio2 4 0>, + <&gpio2 5 0>, <&gpio2 6 0>, <&gpio2 7 0>, <&gpio2 8 0>, <&gpio2 9 0>, <&gpio2 10 0>, <&gpio2 11 0>, + <&gpio2 12 0>, <&gpio2 13 0>, <&gpio2 14 0>, <&gpio2 15 0>, <&gpio2 16 0>, <&gpio2 17 0>, + <&gpio2 18 0>, <&gpio2 19 0>, <&gpio2 20 0>, <&gpio2 21 0>, <&gpio2 22 0>; + + gt_tx_rst_done-gpios = <&gpio3 0 0>, <&gpio3 1 0>, <&gpio3 2 0>, <&gpio3 3 0>, <&gpio3 4 0>, + <&gpio3 5 0>, <&gpio3 6 0>, <&gpio3 7 0>, <&gpio3 8 0>, <&gpio3 9 0>, <&gpio3 10 0>, + <&gpio3 11 0>, <&gpio3 12 0>, <&gpio3 13 0>, <&gpio3 14 0>, <&gpio3 15 0>, <&gpio3 16 0>, + <&gpio3 17 0>, <&gpio3 18 0>, <&gpio3 19 0>, <&gpio3 20 0>, <&gpio3 21 0>, <&gpio3 22 0>, + <&gpio3 23 0>; + + gt_rx_rst_done-gpios = <&gpio3 24 0>, <&gpio3 25 0>, <&gpio3 26 0>, <&gpio3 27 0>, + <&gpio3 28 0>, <&gpio3 29 0>, <&gpio3 30 0>, <&gpio3 31 0>, <&gpio3 32 0>, <&gpio3 33 0>, + <&gpio3 34 0>, <&gpio3 35 0>, <&gpio3 36 0>, <&gpio3 37 0>, <&gpio3 38 0>, <&gpio3 39 0>, + <&gpio3 40 0>, <&gpio3 41 0>, <&gpio3 42 0>, <&gpio3 43 0>, <&gpio3 44 0>, <&gpio3 45 0>, + <&gpio3 46 0>, <&gpio3 47 0>; + + gt_rsts-gpios = <&gpio3 0 0>, <&gpio3 1 0>, <&gpio3 2 0>, <&gpio3 3 0>, <&gpio3 4 0>, <&gpio3 5 0>, + <&gpio3 6 0>, <&gpio3 7 0>, <&gpio3 8 0>, <&gpio3 9 0>, <&gpio3 10 0>, <&gpio3 11 0>, <&gpio3 12 0>, + <&gpio3 13 0>; + }; + +# 5) #Example for Ethernet Offload Engine + - | + axi_ethernet_eoe: ethernet@80020000 { + compatible = "xlnx,axi-ethernet-1.00.a"; + interrupts = <0>; + clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk"; + clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>; + phy-mode = "mii"; + reg = <0x80020000 0x10000>,<0x80008000 0x8000>; + reg-names = "mac", "eoe"; + phy-handle = <&phy2>; + xlnx,rxmem = <0x800>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy2: ethernet-phy@1 { + device_type = "ethernet-phy"; + reg = <1>; + }; }; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/net/xlnx,emaclite.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/net/xlnx,emaclite.yaml @@ -29,6 +29,9 @@ interrupts: maxItems: 1 + clocks: + maxItems: 1 + phy-handle: true local-mac-address: true --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/net/xlnx,gmii-to-rgmii.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/net/xlnx,gmii-to-rgmii.yaml @@ -31,6 +31,13 @@ phy-handle: $ref: ethernet-controller.yaml#/properties/phy-handle + clocks: + maxItems: 1 + + clock-names: + const: clkin + description: 200/375 MHz free-running clock is used as a input clock. + required: - compatible - reg @@ -51,5 +58,7 @@ compatible = "xlnx,gmii-to-rgmii-1.0"; reg = <8>; phy-handle = <&phy>; + clocks = <&dummy>; + clock-names = "clkin"; }; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/nvmem/xlnx,versal-sec-cfg.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/nvmem/xlnx,versal-sec-cfg.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/xlnx,versal-sec-cfg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Secure Configuration driver + +description: | + The versal_sec_cfg node provides access to the BBRAM keys, + BBRAM user data and volatile user keys by using the firmware interface. + +maintainers: + - Harsha + +allOf: + - $ref: nvmem.yaml# + +properties: + compatible: + const: xlnx,versal-sec-cfg + + +unevaluatedProperties: false + +examples: + - | + versal-sec-cfg { + compatible = "xlnx,versal-sec-cfg"; + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + bbram_zeroize: bbram-zeroize@4 { + reg = <0x4 0x4>; + }; + + bbram_key: bbram-key@10 { + reg = <0x10 0x20>; + }; + + bbram_usr: bbram-usr@30 { + reg = <0x30 0x4>; + }; + + bbram_lock: bbram-lock@48 { + reg = <0x48 0x4>; + }; + + user_key0: user-key@110 { + reg = <0x110 0x20>; + }; + + user_key1: user-key@130 { + reg = <0x130 0x20>; + }; + + user_key2: user-key@150 { + reg = <0x150 0x20>; + }; + + user_key3: user-key@170 { + reg = <0x170 0x20>; + }; + + user_key4: user-key@190 { + reg = <0x190 0x20>; + }; + + user_key5: user-key@1b0 { + reg = <0x1b0 0x20>; + }; + + user_key6: user-key@1d0 { + reg = <0x1d0 0x20>; + }; + + user_key7: user-key@1f0 { + reg = <0x1f0 0x20>; + }; + }; + }; + --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/xlnx,zynqmp-nvmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Zynq UltraScale+ MPSoC Non Volatile Memory interface + +description: | + The ZynqMP MPSoC provides access to the hardware related data + like SOC revision, IDCODE and specific purpose efuses. + +maintainers: + - Kalyani Akula + - Praveen Teja Kundanala + +allOf: + - $ref: nvmem.yaml# + +properties: + compatible: + const: xlnx,zynqmp-nvmem-fw + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + nvmem-firmware { + compatible = "xlnx,zynqmp-nvmem-fw"; + #address-cells = <1>; + #size-cells = <1>; + + /* Data cells */ + soc_revision: soc-revision@0 { + reg = <0x0 0x4>; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml @@ -77,6 +77,9 @@ vpcie12v-supply: description: The 12v regulator to use for PCIe. + iommu-map: true + iommu-map-mask: true + required: - compatible - reg --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml @@ -37,6 +37,7 @@ description: This property is needed if using 24MHz OSC for RC's PHY. ep-gpios: + maxItems: 1 description: pre-reset GPIO vpcie12v-supply: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml @@ -17,6 +17,7 @@ enum: - xlnx,versal-cpm-host-1.00 - xlnx,versal-cpm5-host + - xlnx,versal-cpm5-host1 reg: items: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pci/xlnx,xdma-host.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pci/xlnx,xdma-host.yaml @@ -14,10 +14,21 @@ properties: compatible: - const: xlnx,xdma-host-3.00 + enum: + - xlnx,xdma-host-3.00 + - xlnx,qdma-host-3.00 reg: - maxItems: 1 + items: + - description: configuration region and XDMA bridge register. + - description: QDMA bridge register. + minItems: 1 + + reg-names: + items: + - const: cfg + - const: breg + minItems: 1 ranges: maxItems: 2 @@ -76,6 +87,27 @@ - "#interrupt-cells" - interrupt-controller +if: + properties: + compatible: + contains: + enum: + - xlnx,qdma-host-3.00 +then: + properties: + reg: + minItems: 2 + reg-names: + minItems: 2 + required: + - reg-names +else: + properties: + reg: + maxItems: 1 + reg-names: + maxItems: 1 + unevaluatedProperties: false examples: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/perf/xilinx-apm.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/perf/xilinx-apm.yaml @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/perf/xilinx-apm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Axi Performance Monitor + +maintainers: + - Shubhrajyoti Datta + +properties: + compatible: + items: + - enum: + - xlnx,axi-perf-monitor + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + maxItems: 1 + + xlnx,enable-profile: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + description: + Enables the profile mode. + maxItems: 1 + + xlnx,enable-trace: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + description: + Enables trace mode. + maxItems: 1 + + xlnx,num-monitor-slots: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - minimum: 1 + - maximum: 8 + description: + Number of monitor slots. + + xlnx,enable-event-count: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + description: + Enable event count. + + xlnx,enable-event-log: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + description: + Enable event log. + + xlnx,have-sampled-metric-cnt: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + description: + Sampled metric counters enabled in APM. + + xlnx,metric-count-width: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [32, 64] + description: + Metric Counter width. + + xlnx,metric-count-scale: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 4, 8] + description: + Metric Counter scale factor. + + xlnx,num-of-counters: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + description: + Number of counters in APM. + + xlnx,metrics-sample-count-width: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [32, 64] + description: + Sampled metric counter width. + + xlnx,global-count-width: + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [32, 64] + description: + Global Clock counter width. + + xlnx,id-filter-32bit: + description: APM is in 32-bit mode. + type: boolean + +required: + - compatible + - reg + - clocks + - interrupts + +additionalProperties: false + +examples: + - | + apm@44a00000 { + compatible = "xlnx,axi-perf-monitor"; + interrupt-parent = <&axi_intc_1>; + interrupts = <1 2>; + reg = <0x44a00000 0x1000>; + clocks = <&clkc 15>; + xlnx,enable-profile = <0>; + xlnx,enable-trace = <0>; + xlnx,num-monitor-slots = <4>; + xlnx,enable-event-count = <1>; + xlnx,enable-event-log = <1>; + xlnx,have-sampled-metric-cnt = <1>; + xlnx,num-of-counters = <8>; + xlnx,metric-count-width = <32>; + xlnx,metrics-sample-count-width = <32>; + xlnx,global-count-width = <32>; + xlnx,metric-count-scale = <1>; + xlnx,id-filter-32bit; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml @@ -73,7 +73,6 @@ - reg - clocks - clock-names - - power-domains - resets - reset-names - vdda-phy-supply @@ -134,6 +133,21 @@ clock-names: maxItems: 1 + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8996-qmp-ufs-phy + - qcom,msm8998-qmp-ufs-phy + then: + properties: + power-domains: + false + else: + required: + - power-domains + additionalProperties: false examples: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml @@ -15,9 +15,6 @@ properties: compatible: oneOf: - - enum: - - qcom,sc8180x-usb-hs-phy - - qcom,usb-snps-femto-v2-phy - items: - enum: - qcom,sa8775p-usb-hs-phy @@ -26,6 +23,7 @@ - items: - enum: - qcom,sc7280-usb-hs-phy + - qcom,sc8180x-usb-hs-phy - qcom,sdx55-usb-hs-phy - qcom,sdx65-usb-hs-phy - qcom,sm6375-usb-hs-phy --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/phy/xlnx,gt-quad-base.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/phy/xlnx,gt-quad-base.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/xlnx,gt-quad-base.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx DP GTQUAD PHY + +maintainers: + - Jagadeesh Banisetti + +description: | + The Xilinx DP GTQUAD PHY Controller core is designed for enabling + connectivity with Xilinx DP RX and TX with xilinx versal devices. + +properties: + compatible: + items: + - enum: + - xlnx,gt-quad-base-1.1 + + reg: + maxItems: 1 + + clocks: + description: List of clock specifiers + items: + - description: AXI Lite clock + + "#phy-cells": + const: 0 + +required: + - clocks + - compatible + - reg + - '#phy-cells' + +additionalProperties: false + +examples: + - | + gt_quad_base: gt_qb@a4080000 { + clocks = <&misc_clk_0>; + compatible = "xlnx,gt-quad-base-1.1"; + reg = <0xa4080000 0x10000>; + #phy-cells = <0>; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/phy/xlnx,v-hmdi-phy1.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/phy/xlnx,v-hmdi-phy1.yaml @@ -0,0 +1,304 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/xlnx,v-hmdi-phy1.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx HDMI PHY + +maintainers: + - Rajesh Gugulothu + +description: | + The Xilinx HDMI PHY Controller core is designed for enabling plug-and-play + connectivity with Xilinx HDMI 2.1 technology MAC transmit or receive + subsystems. The interface between the video MAC and PHY layers are + standardized to enable ease of use in accessing shared transceiver resource. + +properties: + compatible: + items: + - enum: + - xlnx,v-hdmi-phy1-1.0 + - xlnx,v-hdmi-gt-controller-1.0 + + reg: + maxItems: 1 + + rxch4-sel-gpios: + maxItems: 1 + description: | + Select HDMI 2.1 PHY Rx channel as data or clock based on FRL or TMDS mode. + This property is required only for the boards which has external FMC + card on it. Polarity of this GPIO is GPIO_ACTIVE_LOW + + interrupts: + maxItems: 1 + + clocks: + description: List of clock specifiers + items: + - description: AXI Lite clock + - description: DRP clock + + clock-names: + items: + - const: axi4lite_aclk + - const: drpclk + + xlnx,transceiver-type: + description: | + Gigabit transceiver type that IP configured with.Possible values are as + below - + 5 - GTHE4 + 6 - GTYE4 + 7 - GTYE5 + 8 - GTYP + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [5, 6, 7, 8] + + xlnx,tx-no-of-channels: + description: Max number of channels that Tx configured with. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 4] + + xlnx,rx-no-of-channels: + description: Max number of channels that Rx configured with. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 4] + + xlnx,rx-protocol: + description: Protocol type that Tx is configured with. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 3 + + xlnx,tx-protocol: + description: Protocol type that Rx is configured with. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 3 + + xlnx,nidru: + description: nidru present in the IP or not. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + + xlnx,tx-refclk-sel: + description: Available reference clocks for Tx PLL clock selection + multiplexer. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + + xlnx,rx-refclk-sel: + description: Available reference clocks for Rx PLL clock selection + multiplexer. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + + xlnx,tx-frl-refclk-sel: + description: Available reference clocks for Tx PLL FRL(fixed rate link) + clock selection multiplexer. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + xlnx,rx-frl-refclk-sel: + description: Available reference clocks for Rx PLL FRL(fixed rate link) + clock selection multiplexer. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + + xlnx,tx-pll-selection: + description: Available reference clocks used to driver Tx datapath. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + + xlnx,rx-pll-selection: + description: Available reference clocks used to driver Rx datapath. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + + xlnx,nidru-refclk-sel: + description: Available reference clocks for NI-DRU(non-integer data rate + unit) clock selection multiplexer. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 7 + + xlnx,transceiver-width: + description: Transceiver width that IP is configured with. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [2, 4] + + xlnx,gt-direction: + description: | + Gigabit transceiver direction that IP configured with. Possible values + are as below + 1 - SIMPLE_TX + 2 - SIMPLE_RX + 3 - DUPLEX + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 3] + + xlnx,input-pixels-per-clock: + description: | + Input number of pixel per clock that IP configured with. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [1, 2, 4, 8] + + xlnx,use-gt-ch4-hdmi: + description: | + use 4th GT channel as tx TMDS clock. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + + xlnx,rx-max-gt-line-rate: + description: | + Maxmimum Rx GT linerate that IP is configured with. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [3, 6, 8, 10, 12] + + xlnx,tx-max-gt-line-rate: + description: | + Maxmimum Tx GT linerate that IP is configured with. + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [3, 6, 8, 10, 12] + + xlnx,rx-clk-primitive: + description: | + Rx clock primitive type that IP is configured with. Possible values + are as below. + 0 - MMCM + 1 - PLL + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + + xlnx,tx-clk-primitive: + description: | + Tx clock primitive type that IP is configured with. Possible values + are as below. + 0 - MMCM + 1 - PLL + allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [0, 1] + + "#phy-cells": + const: 0 + +required: + - clock-names + - clocks + - compatible + - interrupts + - reg + - xlnx,transceiver-type + - xlnx,tx-no-of-channels + - xlnx,rx-no-of-channels + - xlnx,tx-refclk-sel + - xlnx,rx-refclk-sel + - xlnx,tx-frl-refclk-sel + - xlnx,rx-frl-refclk-sel + - xlnx,tx-pll-selection + - xlnx,rx-pll-selection + - xlnx,nidru-refclk-sel + - xlnx,transceiver-width + - xlnx,input-pixels-per-clock + - xlnx,use-gt-ch4-hdmi + - xlnx,rx-max-gt-line-rate + - xlnx,tx-max-gt-line-rate + - '#phy-cells' + +additionalProperties: false + +if: + properties: + compatible: + contains: + const: xlnx,v-hdmi-gt-controller-1.0 + +then: + required: + - xlnx,gt-direction + +examples: + - | + v_hdmi_phy1@80040000 { + clock-names = "axi4lite_aclk", "drpclk"; + clocks = <&zynqmp_clk 71>, <&zynqmp_clk 71>; + compatible = "xlnx,v-hdmi-phy1-1.0"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; + reg = <0x80040000 0x10000>; + rxch4-sel-gpios = <&foo_gpio 18 1>; + xlnx,transceiver-type = <5>; + xlnx,tx-no-of-channels = <4>; + xlnx,rx-no-of-channels = <4>; + xlnx,rx-protocol = <2>; + xlnx,tx-protocol = <2>; + xlnx,tx-refclk-sel = <2>; + xlnx,rx-refclk-sel = <0>; + xlnx,tx-frl-refclk-sel = <2>; + xlnx,rx-frl-refclk-sel = <0>; + xlnx,tx-pll-selection = <6>; + xlnx,rx-pll-selection = <0>; + xlnx,nidru = <1>; + xlnx,nidru-refclk-sel = <4>; + xlnx,transceiver-width = <4>; + xlnx,input-pixels-per-clock = <4>; + xlnx,use-gt-ch4-hdmi = <1>; + xlnx,rx-max-gt-line-rate = <0xc>; + xlnx,tx-max-gt-line-rate = <0xc>; + xlnx,rx-clk-primitive = <0x0>; + xlnx,tx-clk-primitive = <0x0>; + #phy-cells = <0>; + }; + v_hdmi_gt@80050000 { + clock-names = "axi4lite_aclk", "drpclk"; + clocks = <&zynqmp_clk 71>, <&zynqmp_clk 71>; + compatible = "xlnx,v-hdmi-gt-controller-1.0"; + interrupt-parent = <&gic>; + interrupts = <0 89 4>; + reg = <0x80050000 0x10000>; + rxch4-sel-gpios = <&foo_gpio1 18 1>; + xlnx,transceiver-type = <5>; + xlnx,tx-no-of-channels = <4>; + xlnx,rx-no-of-channels = <4>; + xlnx,rx-protocol = <2>; + xlnx,tx-protocol = <2>; + xlnx,tx-refclk-sel = <2>; + xlnx,rx-refclk-sel = <0>; + xlnx,tx-frl-refclk-sel = <2>; + xlnx,rx-frl-refclk-sel = <0>; + xlnx,tx-pll-selection = <6>; + xlnx,rx-pll-selection = <0>; + xlnx,nidru = <1>; + xlnx,nidru-refclk-sel = <4>; + xlnx,transceiver-width = <4>; + xlnx,gt-direction = <3>; + xlnx,input-pixels-per-clock = <4>; + xlnx,use-gt-ch4-hdmi = <1>; + xlnx,rx-max-gt-line-rate = <0xc>; + xlnx,tx-max-gt-line-rate = <0xc>; + xlnx,rx-clk-primitive = <0x0>; + xlnx,tx-clk-primitive = <0x0>; + #phy-cells = <0>; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml @@ -97,7 +97,8 @@ then: properties: groups: - enum: [emmc, emmc_rst] + items: + enum: [emmc, emmc_rst] - if: properties: function: @@ -105,8 +106,9 @@ then: properties: groups: - enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw, - rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio] + items: + enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw, + rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio] - if: properties: function: @@ -123,10 +125,11 @@ then: properties: groups: - enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data, - i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws, - i2s1_out_data, i2s2_out_data, i2s3_out_data, - i2s4_out_data] + items: + enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data, + i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws, + i2s1_out_data, i2s2_out_data, i2s3_out_data, + i2s4_out_data] - if: properties: function: @@ -159,10 +162,11 @@ then: properties: groups: - enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken, - pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq, - pcie0_pad_perst, pcie1_pad_perst, pcie_pereset, - pcie_wake, pcie_clkreq] + items: + enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken, + pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq, + pcie0_pad_perst, pcie1_pad_perst, pcie_pereset, + pcie_wake, pcie_clkreq] - if: properties: function: @@ -178,11 +182,12 @@ then: properties: groups: - enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1, - pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0, - pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, - pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3, - pwm_ch7_0, pwm_0, pwm_1] + items: + enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1, + pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0, + pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, + pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3, + pwm_ch7_0, pwm_0, pwm_1] - if: properties: function: @@ -260,33 +265,34 @@ pins: description: An array of strings. Each string contains the name of a pin. - enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0, - RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS, - I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT, - I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1, - G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2, - G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6, - NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0, - MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1, - MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2, - MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3, - MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL, - PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS, - GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N, - PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2, - AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4, - PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA, - WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4, - WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG, - EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS, - EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N, - WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD, - UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD, - UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N, - PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, - GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK, - TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3, - WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6] + items: + enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0, + RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS, + I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT, + I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1, + G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2, + G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6, + NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0, + MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1, + MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2, + MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3, + MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL, + PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS, + GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N, + PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2, + AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4, + PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA, + WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4, + WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG, + EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS, + EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N, + WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD, + UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD, + UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N, + PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, + GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK, + TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3, + WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6] bias-disable: true --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml @@ -72,40 +72,24 @@ description: Specify the alternative function to be configured for the specified pins. - enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2, - atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02, - atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c, - cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4, - cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng, - cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1, - dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c, - jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2, - mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws, - mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0, - mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk, - phase_flag0, phase_flag1, phase_flag10, phase_flag11, - phase_flag12, phase_flag13, phase_flag14, phase_flag15, - phase_flag16, phase_flag17, phase_flag18, phase_flag19, - phase_flag2, phase_flag20, phase_flag21, phase_flag22, - phase_flag23, phase_flag24, phase_flag25, phase_flag26, - phase_flag27, phase_flag28, phase_flag29, phase_flag3, - phase_flag30, phase_flag31, phase_flag4, phase_flag5, - phase_flag6, phase_flag7, phase_flag8, phase_flag9, - pll_bist, pll_clk, prng_rosc0, prng_rosc1, prng_rosc2, - prng_rosc3, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1, - qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14, - qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5, - qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable, - qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request, - qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss, - qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5, - qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3, - qup1_se4, qup1_se5, qup1_se6, sd_write, tb_trig, tgu_ch0, - tgu_ch1, tgu_ch2, tgu_ch3, tmess_prng0, tmess_prng1, - tmess_prng2, tmess_prng3, tsense_pwm1, tsense_pwm2, uim0_clk, - uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data, - uim1_present, uim1_reset, usb0_hs, usb0_phy, vfr_0, vfr_1, - vsense_trigger ] + enum: [ gpio, atest_char, atest_usb0, audio_ref_clk, cam_mclk, + cci_async_in0, cci_i2c, cci, cmu_rng, coex_uart1_rx, + coex_uart1_tx, cri_trng, dbg_out_clk, ddr_bist, + ddr_pxi0_test, ddr_pxi1_test, gcc_gp1_clk, gcc_gp2_clk, + gcc_gp3_clk, host2wlan_sol, ibi_i3c_qup0, ibi_i3c_qup1, + jitter_bist_ref, mdp_vsync0_out, mdp_vsync1_out, + mdp_vsync2_out, mdp_vsync3_out, mdp_vsync, nav, + pcie0_clk_req, phase_flag, pll_bist_sync, pll_clk_aux, + prng_rosc, qdss_cti_trig0, qdss_cti_trig1, qdss_gpio, + qlink0_enable, qlink0_request, qlink0_wmss_reset, + qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, + qup1_se0, qup1_se1, qup1_se2, qup1_se2_l2, qup1_se3, + qup1_se4, sd_write_protect, tb_trig_sdc1, tb_trig_sdc2, + tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout, + tgu_ch3_trigout, tmess_prng, tsense_pwm1_out, + tsense_pwm2_out, uim0, uim1, usb0_hs_ac, usb0_phy_ps, + vfr_0_mira, vfr_0_mirb, vfr_1, vsense_trigger_mirnat, + wlan1_adc_dtest0, wlan1_adc_dtest1 ] required: - pins --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml @@ -47,187 +47,208 @@ List of groups to select (either this or "pins" must be specified), available groups for this subnode. items: - enum: [ethernet0_0_grp, ethernet1_0_grp, ethernet2_0_grp, - ethernet3_0_grp, gemtsu0_0_grp, gemtsu0_1_grp, - gemtsu0_2_grp, mdio0_0_grp, mdio1_0_grp, - mdio1_1_grp, mdio2_0_grp, mdio3_0_grp, - qspi0_0_grp, qspi_ss_0_grp, qspi_fbclk_0_grp, - spi0_0_grp, spi0_ss_0_grp, spi0_ss_1_grp, - spi0_ss_2_grp, spi0_1_grp, spi0_ss_3_grp, - spi0_ss_4_grp, spi0_ss_5_grp, spi0_2_grp, - spi0_ss_6_grp, spi0_ss_7_grp, spi0_ss_8_grp, - spi0_3_grp, spi0_ss_9_grp, spi0_ss_10_grp, - spi0_ss_11_grp, spi0_4_grp, spi0_ss_12_grp, - spi0_ss_13_grp, spi0_ss_14_grp, spi0_5_grp, - spi0_ss_15_grp, spi0_ss_16_grp, spi0_ss_17_grp, - spi1_0_grp, spi1_ss_0_grp, spi1_ss_1_grp, - spi1_ss_2_grp, spi1_1_grp, spi1_ss_3_grp, - spi1_ss_4_grp, spi1_ss_5_grp, spi1_2_grp, - spi1_ss_6_grp, spi1_ss_7_grp, spi1_ss_8_grp, - spi1_3_grp, spi1_ss_9_grp, spi1_ss_10_grp, - spi1_ss_11_grp, spi1_4_grp, spi1_ss_12_grp, - spi1_ss_13_grp, spi1_ss_14_grp, spi1_5_grp, - spi1_ss_15_grp, spi1_ss_16_grp, spi1_ss_17_grp, - sdio0_0_grp, sdio0_1_grp, sdio0_2_grp, - sdio0_3_grp, sdio0_4_grp, sdio0_5_grp, - sdio0_6_grp, sdio0_7_grp, sdio0_8_grp, - sdio0_9_grp, sdio0_10_grp, sdio0_11_grp, - sdio0_12_grp, sdio0_13_grp, sdio0_14_grp, - sdio0_15_grp, sdio0_16_grp, sdio0_17_grp, - sdio0_18_grp, sdio0_19_grp, sdio0_20_grp, - sdio0_21_grp, sdio0_22_grp, sdio0_23_grp, - sdio0_24_grp, sdio0_25_grp, sdio0_26_grp, - sdio0_27_grp, sdio0_28_grp, sdio0_29_grp, - sdio0_30_grp, sdio0_31_grp, sdio0_32_grp, - sdio0_pc_0_grp, sdio0_cd_0_grp, sdio0_wp_0_grp, - sdio0_pc_1_grp, sdio0_cd_1_grp, sdio0_wp_1_grp, - sdio0_pc_2_grp, sdio0_cd_2_grp, sdio0_wp_2_grp, - sdio1_0_grp, sdio1_1_grp, sdio1_2_grp, - sdio1_3_grp, sdio1_4_grp, sdio1_5_grp, - sdio1_6_grp, sdio1_7_grp, sdio1_8_grp, - sdio1_9_grp, sdio1_10_grp, sdio1_11_grp, - sdio1_12_grp, sdio1_13_grp, sdio1_14_grp, - sdio1_15_grp, sdio1_pc_0_grp, sdio1_cd_0_grp, - sdio1_wp_0_grp, sdio1_pc_1_grp, sdio1_cd_1_grp, - sdio1_wp_1_grp, nand0_0_grp, nand0_ce_0_grp, - nand0_rb_0_grp, nand0_dqs_0_grp, nand0_ce_1_grp, - nand0_rb_1_grp, nand0_dqs_1_grp, can0_0_grp, - can0_1_grp, can0_2_grp, can0_3_grp, - can0_4_grp, can0_5_grp, can0_6_grp, - can0_7_grp, can0_8_grp, can0_9_grp, - can0_10_grp, can0_11_grp, can0_12_grp, - can0_13_grp, can0_14_grp, can0_15_grp, - can0_16_grp, can0_17_grp, can0_18_grp, - can1_0_grp, can1_1_grp, can1_2_grp, - can1_3_grp, can1_4_grp, can1_5_grp, - can1_6_grp, can1_7_grp, can1_8_grp, - can1_9_grp, can1_10_grp, can1_11_grp, - can1_12_grp, can1_13_grp, can1_14_grp, - can1_15_grp, can1_16_grp, can1_17_grp, - can1_18_grp, can1_19_grp, uart0_0_grp, - uart0_1_grp, uart0_2_grp, uart0_3_grp, - uart0_4_grp, uart0_5_grp, uart0_6_grp, - uart0_7_grp, uart0_8_grp, uart0_9_grp, - uart0_10_grp, uart0_11_grp, uart0_12_grp, - uart0_13_grp, uart0_14_grp, uart0_15_grp, - uart0_16_grp, uart0_17_grp, uart0_18_grp, - uart1_0_grp, uart1_1_grp, uart1_2_grp, - uart1_3_grp, uart1_4_grp, uart1_5_grp, - uart1_6_grp, uart1_7_grp, uart1_8_grp, - uart1_9_grp, uart1_10_grp, uart1_11_grp, - uart1_12_grp, uart1_13_grp, uart1_14_grp, - uart1_15_grp, uart1_16_grp, uart1_17_grp, - uart1_18_grp, i2c0_0_grp, i2c0_1_grp, - i2c0_2_grp, i2c0_3_grp, i2c0_4_grp, - i2c0_5_grp, i2c0_6_grp, i2c0_7_grp, - i2c0_8_grp, i2c0_9_grp, i2c0_10_grp, - i2c0_11_grp, i2c0_12_grp, i2c0_13_grp, - i2c0_14_grp, i2c0_15_grp, i2c0_16_grp, - i2c0_17_grp, i2c0_18_grp, i2c1_0_grp, - i2c1_1_grp, i2c1_2_grp, i2c1_3_grp, - i2c1_4_grp, i2c1_5_grp, i2c1_6_grp, - i2c1_7_grp, i2c1_8_grp, i2c1_9_grp, - i2c1_10_grp, i2c1_11_grp, i2c1_12_grp, - i2c1_13_grp, i2c1_14_grp, i2c1_15_grp, - i2c1_16_grp, i2c1_17_grp, i2c1_18_grp, - i2c1_19_grp, ttc0_clk_0_grp, ttc0_wav_0_grp, - ttc0_clk_1_grp, ttc0_wav_1_grp, ttc0_clk_2_grp, - ttc0_wav_2_grp, ttc0_clk_3_grp, ttc0_wav_3_grp, - ttc0_clk_4_grp, ttc0_wav_4_grp, ttc0_clk_5_grp, - ttc0_wav_5_grp, ttc0_clk_6_grp, ttc0_wav_6_grp, - ttc0_clk_7_grp, ttc0_wav_7_grp, ttc0_clk_8_grp, - ttc0_wav_8_grp, ttc1_clk_0_grp, ttc1_wav_0_grp, - ttc1_clk_1_grp, ttc1_wav_1_grp, ttc1_clk_2_grp, - ttc1_wav_2_grp, ttc1_clk_3_grp, ttc1_wav_3_grp, - ttc1_clk_4_grp, ttc1_wav_4_grp, ttc1_clk_5_grp, - ttc1_wav_5_grp, ttc1_clk_6_grp, ttc1_wav_6_grp, - ttc1_clk_7_grp, ttc1_wav_7_grp, ttc1_clk_8_grp, - ttc1_wav_8_grp, ttc2_clk_0_grp, ttc2_wav_0_grp, - ttc2_clk_1_grp, ttc2_wav_1_grp, ttc2_clk_2_grp, - ttc2_wav_2_grp, ttc2_clk_3_grp, ttc2_wav_3_grp, - ttc2_clk_4_grp, ttc2_wav_4_grp, ttc2_clk_5_grp, - ttc2_wav_5_grp, ttc2_clk_6_grp, ttc2_wav_6_grp, - ttc2_clk_7_grp, ttc2_wav_7_grp, ttc2_clk_8_grp, - ttc2_wav_8_grp, ttc3_clk_0_grp, ttc3_wav_0_grp, - ttc3_clk_1_grp, ttc3_wav_1_grp, ttc3_clk_2_grp, - ttc3_wav_2_grp, ttc3_clk_3_grp, ttc3_wav_3_grp, - ttc3_clk_4_grp, ttc3_wav_4_grp, ttc3_clk_5_grp, - ttc3_wav_5_grp, ttc3_clk_6_grp, ttc3_wav_6_grp, - ttc3_clk_7_grp, ttc3_wav_7_grp, ttc3_clk_8_grp, - ttc3_wav_8_grp, swdt0_clk_0_grp, swdt0_rst_0_grp, - swdt0_clk_1_grp, swdt0_rst_1_grp, swdt0_clk_2_grp, - swdt0_rst_2_grp, swdt0_clk_3_grp, swdt0_rst_3_grp, - swdt0_clk_4_grp, swdt0_rst_4_grp, swdt0_clk_5_grp, - swdt0_rst_5_grp, swdt0_clk_6_grp, swdt0_rst_6_grp, - swdt0_clk_7_grp, swdt0_rst_7_grp, swdt0_clk_8_grp, - swdt0_rst_8_grp, swdt0_clk_9_grp, swdt0_rst_9_grp, - swdt0_clk_10_grp, swdt0_rst_10_grp, swdt0_clk_11_grp, - swdt0_rst_11_grp, swdt0_clk_12_grp, swdt0_rst_12_grp, - swdt1_clk_0_grp, swdt1_rst_0_grp, swdt1_clk_1_grp, - swdt1_rst_1_grp, swdt1_clk_2_grp, swdt1_rst_2_grp, - swdt1_clk_3_grp, swdt1_rst_3_grp, swdt1_clk_4_grp, - swdt1_rst_4_grp, swdt1_clk_5_grp, swdt1_rst_5_grp, - swdt1_clk_6_grp, swdt1_rst_6_grp, swdt1_clk_7_grp, - swdt1_rst_7_grp, swdt1_clk_8_grp, swdt1_rst_8_grp, - swdt1_clk_9_grp, swdt1_rst_9_grp, swdt1_clk_10_grp, - swdt1_rst_10_grp, swdt1_clk_11_grp, swdt1_rst_11_grp, - swdt1_clk_12_grp, swdt1_rst_12_grp, gpio0_0_grp, - gpio0_1_grp, gpio0_2_grp, gpio0_3_grp, - gpio0_4_grp, gpio0_5_grp, gpio0_6_grp, - gpio0_7_grp, gpio0_8_grp, gpio0_9_grp, - gpio0_10_grp, gpio0_11_grp, gpio0_12_grp, - gpio0_13_grp, gpio0_14_grp, gpio0_15_grp, - gpio0_16_grp, gpio0_17_grp, gpio0_18_grp, - gpio0_19_grp, gpio0_20_grp, gpio0_21_grp, - gpio0_22_grp, gpio0_23_grp, gpio0_24_grp, - gpio0_25_grp, gpio0_26_grp, gpio0_27_grp, - gpio0_28_grp, gpio0_29_grp, gpio0_30_grp, - gpio0_31_grp, gpio0_32_grp, gpio0_33_grp, - gpio0_34_grp, gpio0_35_grp, gpio0_36_grp, - gpio0_37_grp, gpio0_38_grp, gpio0_39_grp, - gpio0_40_grp, gpio0_41_grp, gpio0_42_grp, - gpio0_43_grp, gpio0_44_grp, gpio0_45_grp, - gpio0_46_grp, gpio0_47_grp, gpio0_48_grp, - gpio0_49_grp, gpio0_50_grp, gpio0_51_grp, - gpio0_52_grp, gpio0_53_grp, gpio0_54_grp, - gpio0_55_grp, gpio0_56_grp, gpio0_57_grp, - gpio0_58_grp, gpio0_59_grp, gpio0_60_grp, - gpio0_61_grp, gpio0_62_grp, gpio0_63_grp, - gpio0_64_grp, gpio0_65_grp, gpio0_66_grp, - gpio0_67_grp, gpio0_68_grp, gpio0_69_grp, - gpio0_70_grp, gpio0_71_grp, gpio0_72_grp, - gpio0_73_grp, gpio0_74_grp, gpio0_75_grp, - gpio0_76_grp, gpio0_77_grp, usb0_0_grp, - usb1_0_grp, pmu0_0_grp, pmu0_1_grp, - pmu0_2_grp, pmu0_3_grp, pmu0_4_grp, - pmu0_5_grp, pmu0_6_grp, pmu0_7_grp, - pmu0_8_grp, pmu0_9_grp, pmu0_10_grp, - pmu0_11_grp, pcie0_0_grp, pcie0_1_grp, - pcie0_2_grp, pcie0_3_grp, pcie0_4_grp, - pcie0_5_grp, pcie0_6_grp, pcie0_7_grp, - csu0_0_grp, csu0_1_grp, csu0_2_grp, - csu0_3_grp, csu0_4_grp, csu0_5_grp, - csu0_6_grp, csu0_7_grp, csu0_8_grp, - csu0_9_grp, csu0_10_grp, csu0_11_grp, - dpaux0_0_grp, dpaux0_1_grp, dpaux0_2_grp, - dpaux0_3_grp, pjtag0_0_grp, pjtag0_1_grp, - pjtag0_2_grp, pjtag0_3_grp, pjtag0_4_grp, - pjtag0_5_grp, trace0_0_grp, trace0_clk_0_grp, - trace0_1_grp, trace0_clk_1_grp, trace0_2_grp, - trace0_clk_2_grp, testscan0_0_grp] + allOf: + - if: + properties: + compatible: + contains: + const: xlnx,zynqmp-pinctrl + then: + enum: [ethernet0_0_grp, ethernet1_0_grp, ethernet2_0_grp, + ethernet3_0_grp, gemtsu0_0_grp, gemtsu0_1_grp, + gemtsu0_2_grp, mdio0_0_grp, mdio1_0_grp, + mdio1_1_grp, mdio2_0_grp, mdio3_0_grp, + qspi0_0_grp, qspi_ss_0_grp, qspi_fbclk_0_grp, + spi0_0_grp, spi0_ss_0_grp, spi0_ss_1_grp, + spi0_ss_2_grp, spi0_1_grp, spi0_ss_3_grp, + spi0_ss_4_grp, spi0_ss_5_grp, spi0_2_grp, + spi0_ss_6_grp, spi0_ss_7_grp, spi0_ss_8_grp, + spi0_3_grp, spi0_ss_9_grp, spi0_ss_10_grp, + spi0_ss_11_grp, spi0_4_grp, spi0_ss_12_grp, + spi0_ss_13_grp, spi0_ss_14_grp, spi0_5_grp, + spi0_ss_15_grp, spi0_ss_16_grp, spi0_ss_17_grp, + spi1_0_grp, spi1_ss_0_grp, spi1_ss_1_grp, + spi1_ss_2_grp, spi1_1_grp, spi1_ss_3_grp, + spi1_ss_4_grp, spi1_ss_5_grp, spi1_2_grp, + spi1_ss_6_grp, spi1_ss_7_grp, spi1_ss_8_grp, + spi1_3_grp, spi1_ss_9_grp, spi1_ss_10_grp, + spi1_ss_11_grp, spi1_4_grp, spi1_ss_12_grp, + spi1_ss_13_grp, spi1_ss_14_grp, spi1_5_grp, + spi1_ss_15_grp, spi1_ss_16_grp, spi1_ss_17_grp, + sdio0_0_grp, sdio0_1_grp, sdio0_2_grp, + sdio0_3_grp, sdio0_4_grp, sdio0_5_grp, + sdio0_6_grp, sdio0_7_grp, sdio0_8_grp, + sdio0_9_grp, sdio0_10_grp, sdio0_11_grp, + sdio0_12_grp, sdio0_13_grp, sdio0_14_grp, + sdio0_15_grp, sdio0_16_grp, sdio0_17_grp, + sdio0_18_grp, sdio0_19_grp, sdio0_20_grp, + sdio0_21_grp, sdio0_22_grp, sdio0_23_grp, + sdio0_24_grp, sdio0_25_grp, sdio0_26_grp, + sdio0_27_grp, sdio0_28_grp, sdio0_29_grp, + sdio0_30_grp, sdio0_31_grp, sdio0_32_grp, + sdio0_pc_0_grp, sdio0_cd_0_grp, sdio0_wp_0_grp, + sdio0_pc_1_grp, sdio0_cd_1_grp, sdio0_wp_1_grp, + sdio0_pc_2_grp, sdio0_cd_2_grp, sdio0_wp_2_grp, + sdio1_0_grp, sdio1_1_grp, sdio1_2_grp, + sdio1_3_grp, sdio1_4_grp, sdio1_5_grp, + sdio1_6_grp, sdio1_7_grp, sdio1_8_grp, + sdio1_9_grp, sdio1_10_grp, sdio1_11_grp, + sdio1_12_grp, sdio1_13_grp, sdio1_14_grp, + sdio1_15_grp, sdio1_pc_0_grp, sdio1_cd_0_grp, + sdio1_wp_0_grp, sdio1_pc_1_grp, sdio1_cd_1_grp, + sdio1_wp_1_grp, nand0_0_grp, nand0_ce_0_grp, + nand0_rb_0_grp, nand0_dqs_0_grp, nand0_ce_1_grp, + nand0_rb_1_grp, nand0_dqs_1_grp, can0_0_grp, + can0_1_grp, can0_2_grp, can0_3_grp, + can0_4_grp, can0_5_grp, can0_6_grp, + can0_7_grp, can0_8_grp, can0_9_grp, + can0_10_grp, can0_11_grp, can0_12_grp, + can0_13_grp, can0_14_grp, can0_15_grp, + can0_16_grp, can0_17_grp, can0_18_grp, + can1_0_grp, can1_1_grp, can1_2_grp, + can1_3_grp, can1_4_grp, can1_5_grp, + can1_6_grp, can1_7_grp, can1_8_grp, + can1_9_grp, can1_10_grp, can1_11_grp, + can1_12_grp, can1_13_grp, can1_14_grp, + can1_15_grp, can1_16_grp, can1_17_grp, + can1_18_grp, can1_19_grp, uart0_0_grp, + uart0_1_grp, uart0_2_grp, uart0_3_grp, + uart0_4_grp, uart0_5_grp, uart0_6_grp, + uart0_7_grp, uart0_8_grp, uart0_9_grp, + uart0_10_grp, uart0_11_grp, uart0_12_grp, + uart0_13_grp, uart0_14_grp, uart0_15_grp, + uart0_16_grp, uart0_17_grp, uart0_18_grp, + uart1_0_grp, uart1_1_grp, uart1_2_grp, + uart1_3_grp, uart1_4_grp, uart1_5_grp, + uart1_6_grp, uart1_7_grp, uart1_8_grp, + uart1_9_grp, uart1_10_grp, uart1_11_grp, + uart1_12_grp, uart1_13_grp, uart1_14_grp, + uart1_15_grp, uart1_16_grp, uart1_17_grp, + uart1_18_grp, i2c0_0_grp, i2c0_1_grp, + i2c0_2_grp, i2c0_3_grp, i2c0_4_grp, + i2c0_5_grp, i2c0_6_grp, i2c0_7_grp, + i2c0_8_grp, i2c0_9_grp, i2c0_10_grp, + i2c0_11_grp, i2c0_12_grp, i2c0_13_grp, + i2c0_14_grp, i2c0_15_grp, i2c0_16_grp, + i2c0_17_grp, i2c0_18_grp, i2c1_0_grp, + i2c1_1_grp, i2c1_2_grp, i2c1_3_grp, + i2c1_4_grp, i2c1_5_grp, i2c1_6_grp, + i2c1_7_grp, i2c1_8_grp, i2c1_9_grp, + i2c1_10_grp, i2c1_11_grp, i2c1_12_grp, + i2c1_13_grp, i2c1_14_grp, i2c1_15_grp, + i2c1_16_grp, i2c1_17_grp, i2c1_18_grp, + i2c1_19_grp, ttc0_clk_0_grp, ttc0_wav_0_grp, + ttc0_clk_1_grp, ttc0_wav_1_grp, ttc0_clk_2_grp, + ttc0_wav_2_grp, ttc0_clk_3_grp, ttc0_wav_3_grp, + ttc0_clk_4_grp, ttc0_wav_4_grp, ttc0_clk_5_grp, + ttc0_wav_5_grp, ttc0_clk_6_grp, ttc0_wav_6_grp, + ttc0_clk_7_grp, ttc0_wav_7_grp, ttc0_clk_8_grp, + ttc0_wav_8_grp, ttc1_clk_0_grp, ttc1_wav_0_grp, + ttc1_clk_1_grp, ttc1_wav_1_grp, ttc1_clk_2_grp, + ttc1_wav_2_grp, ttc1_clk_3_grp, ttc1_wav_3_grp, + ttc1_clk_4_grp, ttc1_wav_4_grp, ttc1_clk_5_grp, + ttc1_wav_5_grp, ttc1_clk_6_grp, ttc1_wav_6_grp, + ttc1_clk_7_grp, ttc1_wav_7_grp, ttc1_clk_8_grp, + ttc1_wav_8_grp, ttc2_clk_0_grp, ttc2_wav_0_grp, + ttc2_clk_1_grp, ttc2_wav_1_grp, ttc2_clk_2_grp, + ttc2_wav_2_grp, ttc2_clk_3_grp, ttc2_wav_3_grp, + ttc2_clk_4_grp, ttc2_wav_4_grp, ttc2_clk_5_grp, + ttc2_wav_5_grp, ttc2_clk_6_grp, ttc2_wav_6_grp, + ttc2_clk_7_grp, ttc2_wav_7_grp, ttc2_clk_8_grp, + ttc2_wav_8_grp, ttc3_clk_0_grp, ttc3_wav_0_grp, + ttc3_clk_1_grp, ttc3_wav_1_grp, ttc3_clk_2_grp, + ttc3_wav_2_grp, ttc3_clk_3_grp, ttc3_wav_3_grp, + ttc3_clk_4_grp, ttc3_wav_4_grp, ttc3_clk_5_grp, + ttc3_wav_5_grp, ttc3_clk_6_grp, ttc3_wav_6_grp, + ttc3_clk_7_grp, ttc3_wav_7_grp, ttc3_clk_8_grp, + ttc3_wav_8_grp, swdt0_clk_0_grp, swdt0_rst_0_grp, + swdt0_clk_1_grp, swdt0_rst_1_grp, swdt0_clk_2_grp, + swdt0_rst_2_grp, swdt0_clk_3_grp, swdt0_rst_3_grp, + swdt0_clk_4_grp, swdt0_rst_4_grp, swdt0_clk_5_grp, + swdt0_rst_5_grp, swdt0_clk_6_grp, swdt0_rst_6_grp, + swdt0_clk_7_grp, swdt0_rst_7_grp, swdt0_clk_8_grp, + swdt0_rst_8_grp, swdt0_clk_9_grp, swdt0_rst_9_grp, + swdt0_clk_10_grp, swdt0_rst_10_grp, swdt0_clk_11_grp, + swdt0_rst_11_grp, swdt0_clk_12_grp, swdt0_rst_12_grp, + swdt1_clk_0_grp, swdt1_rst_0_grp, swdt1_clk_1_grp, + swdt1_rst_1_grp, swdt1_clk_2_grp, swdt1_rst_2_grp, + swdt1_clk_3_grp, swdt1_rst_3_grp, swdt1_clk_4_grp, + swdt1_rst_4_grp, swdt1_clk_5_grp, swdt1_rst_5_grp, + swdt1_clk_6_grp, swdt1_rst_6_grp, swdt1_clk_7_grp, + swdt1_rst_7_grp, swdt1_clk_8_grp, swdt1_rst_8_grp, + swdt1_clk_9_grp, swdt1_rst_9_grp, swdt1_clk_10_grp, + swdt1_rst_10_grp, swdt1_clk_11_grp, swdt1_rst_11_grp, + swdt1_clk_12_grp, swdt1_rst_12_grp, gpio0_0_grp, + gpio0_1_grp, gpio0_2_grp, gpio0_3_grp, + gpio0_4_grp, gpio0_5_grp, gpio0_6_grp, + gpio0_7_grp, gpio0_8_grp, gpio0_9_grp, + gpio0_10_grp, gpio0_11_grp, gpio0_12_grp, + gpio0_13_grp, gpio0_14_grp, gpio0_15_grp, + gpio0_16_grp, gpio0_17_grp, gpio0_18_grp, + gpio0_19_grp, gpio0_20_grp, gpio0_21_grp, + gpio0_22_grp, gpio0_23_grp, gpio0_24_grp, + gpio0_25_grp, gpio0_26_grp, gpio0_27_grp, + gpio0_28_grp, gpio0_29_grp, gpio0_30_grp, + gpio0_31_grp, gpio0_32_grp, gpio0_33_grp, + gpio0_34_grp, gpio0_35_grp, gpio0_36_grp, + gpio0_37_grp, gpio0_38_grp, gpio0_39_grp, + gpio0_40_grp, gpio0_41_grp, gpio0_42_grp, + gpio0_43_grp, gpio0_44_grp, gpio0_45_grp, + gpio0_46_grp, gpio0_47_grp, gpio0_48_grp, + gpio0_49_grp, gpio0_50_grp, gpio0_51_grp, + gpio0_52_grp, gpio0_53_grp, gpio0_54_grp, + gpio0_55_grp, gpio0_56_grp, gpio0_57_grp, + gpio0_58_grp, gpio0_59_grp, gpio0_60_grp, + gpio0_61_grp, gpio0_62_grp, gpio0_63_grp, + gpio0_64_grp, gpio0_65_grp, gpio0_66_grp, + gpio0_67_grp, gpio0_68_grp, gpio0_69_grp, + gpio0_70_grp, gpio0_71_grp, gpio0_72_grp, + gpio0_73_grp, gpio0_74_grp, gpio0_75_grp, + gpio0_76_grp, gpio0_77_grp, usb0_0_grp, + usb1_0_grp, pmu0_0_grp, pmu0_1_grp, + pmu0_2_grp, pmu0_3_grp, pmu0_4_grp, + pmu0_5_grp, pmu0_6_grp, pmu0_7_grp, + pmu0_8_grp, pmu0_9_grp, pmu0_10_grp, + pmu0_11_grp, pcie0_0_grp, pcie0_1_grp, + pcie0_2_grp, pcie0_3_grp, pcie0_4_grp, + pcie0_5_grp, pcie0_6_grp, pcie0_7_grp, + csu0_0_grp, csu0_1_grp, csu0_2_grp, + csu0_3_grp, csu0_4_grp, csu0_5_grp, + csu0_6_grp, csu0_7_grp, csu0_8_grp, + csu0_9_grp, csu0_10_grp, csu0_11_grp, + dpaux0_0_grp, dpaux0_1_grp, dpaux0_2_grp, + dpaux0_3_grp, pjtag0_0_grp, pjtag0_1_grp, + pjtag0_2_grp, pjtag0_3_grp, pjtag0_4_grp, + pjtag0_5_grp, trace0_0_grp, trace0_clk_0_grp, + trace0_1_grp, trace0_clk_1_grp, trace0_2_grp, + trace0_clk_2_grp, testscan0_0_grp] + else: + enum: [sd1_0_grp, sd1_1_grp, sd1_2_grp, sd1_3_grp, sd1_4_grp, sd1_5_grp, + sd1_6_grp, sd1_7_grp, sd1_8_grp, sd1_9_grp, sd1_10_grp, sd1_11_grp, + sd1_12_grp, sd1_13_grp, sd1_14_grp, sd1_15_grp, sd1_pc_0_grp, + sd1_cd_0_grp, sd1_wp_0_grp, sd1_pc_1_grp, sd1_cd_1_grp, sd1_wp_1_grp] maxItems: 78 function: description: Specify the alternative function to be configured for the given pin groups. - enum: [ethernet0, ethernet1, ethernet2, ethernet3, gemtsu0, usb0, usb1, mdio0, - mdio1, mdio2, mdio3, qspi0, qspi_fbclk, qspi_ss, spi0, spi1, spi0_ss, - spi1_ss, sdio0, sdio0_pc, sdio0_wp, sdio0_cd, sdio1, sdio1_pc, sdio1_wp, - sdio1_cd, nand0, nand0_ce, nand0_rb, nand0_dqs, can0, can1, uart0, uart1, - i2c0, i2c1, ttc0_clk, ttc0_wav, ttc1_clk, ttc1_wav, ttc2_clk, ttc2_wav, - ttc3_clk, ttc3_wav, swdt0_clk, swdt0_rst, swdt1_clk, swdt1_rst, gpio0, pmu0, - pcie0, csu0, dpaux0, pjtag0, trace0, trace0_clk, testscan0] + allOf: + - if: + properties: + compatible: + contains: + const: xlnx,zynqmp-pinctrl + then: + enum: [ethernet0, ethernet1, ethernet2, ethernet3, gemtsu0, usb0, usb1, mdio0, + mdio1, mdio2, mdio3, qspi0, qspi_fbclk, qspi_ss, spi0, spi1, spi0_ss, + spi1_ss, sdio0, sdio0_pc, sdio0_wp, sdio0_cd, sdio1, sdio1_pc, sdio1_wp, + sdio1_cd, nand0, nand0_ce, nand0_rb, nand0_dqs, can0, can1, uart0, uart1, + i2c0, i2c1, ttc0_clk, ttc0_wav, ttc1_clk, ttc1_wav, ttc2_clk, ttc2_wav, + ttc3_clk, ttc3_wav, swdt0_clk, swdt0_rst, swdt1_clk, swdt1_rst, gpio0, pmu0, + pcie0, csu0, dpaux0, pjtag0, trace0, trace0_clk, testscan0] + else: + enum: [sd1, sd1_pc, sd1_wp, sd1_cd] required: - groups @@ -251,7 +272,16 @@ description: List of pin names to select in this subnode. items: - pattern: '^MIO([0-9]|[1-6][0-9]|7[0-7])$' + allOf: + - if: + properties: + compatible: + contains: + const: xlnx,zynqmp-pinctrl + then: + pattern: '^MIO([0-9]|[1-6][0-9]|7[0-7])$' + else: + pattern: '^((LPD|PMC)_)?MIO([0-9]|[1-6][0-9]|7[0-7])$' maxItems: 78 bias-pull-up: true --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/ptp/ptp-xilinx.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/ptp/ptp-xilinx.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ptp/ptp-xilinx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx 1588 PTP timer-syncer + +maintainers: + - Harini Katakam + +description: | + Xilinx 1588 PTP timer-syncer IP provides precision timing functionality + along with capability for time and fine adjustment. This IP is provided + for use with Xilinx Ethernet MAC with HW timestamping capability. + +properties: + compatible: + enum: + - xlnx,timer-syncer-1588-1.0 # Deprecated + - xlnx,timer-syncer-1588-2.0 + - xlnx,timer-syncer-1588-3.0 + + reg: + description: | + Offset and length of the register set for the device. + + xlnx,has-timer-syncer: + type: boolean + description: | + Describes the timerIP modes. Supported modes are system timer, + system and port timer mode. If property is present then its + a system timer mode else system and port timer mode. + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + ptp_timer@80000000 { + compatible = "xlnx,timer-syncer-1588-2.0"; + reg = <0x80000000 0x10000>; + xlnx,has-timer-syncer; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/remoteproc/xilinx,zynqmp-r5-remoteproc.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/remoteproc/xilinx,zynqmp-r5-remoteproc.yaml @@ -0,0 +1,216 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/remoteproc/xilinx,zynqmp-r5-remoteproc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx R5 remote processor controller + +description: + This document defines the binding for the remoteproc component that loads and + boots firmwares on the Xilinx Zynqmp and Versal family chipsets. + + Note that the Linux has global addressing view of the R5-related memory (TCM) + so the absolute address ranges are provided in TCM reg's. + +maintainers: + - Ben Levinsky + +properties: + $nodename: + pattern: "^r5[f|2]ss(@.*)?" + + compatible: + enum: + - xlnx,zynqmp-r5-remoteproc + - xlnx,versal-r5-remoteproc + - xlnx,versal-net-r52-remoteproc + + reg: + items: + - description: Address and Size of Xilinx RPU Configuration register + + "#address-cells": + const: 2 + + "#size-cells": + const: 2 + + ranges: true + +# Optional properties: +# -------------------- + xlnx,cluster-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1] + description: | + Configuration Mode for the Dual R5F cores within the R5F cluster. + Should be either a value of 0 (LockStep mode) or 1 (Split mode), + default is LockStep mode if omitted. + +# R5F Processor Child Nodes: +# ========================== + +patternProperties: + "^r5[f|2]_[a-f0-9]+$": + type: object + description: | + The R5F Sub-System device node should define one or two R5F child nodes, + each node representing a Xilinx instantiation of the Arm Cortex R5F core. + There should be one or two child nodes if the R5F is in Split mode and + one child node if the R5F is in Lockstep mode. + + In Split mode each R5F core has two associated TCM Banks. R5_0 has + TCM Banks 0A and 0B and R5_1 has TCM Banks 1A and 1B. + + In Lockstep mode only one R5F child node should be defined. This one + child has access to TCM Banks 0A, 0B, 1A and 1B and any of the four can + be included in the child R5F's sram property. + + This also supports arm-cortexr52 clusters on Versal-net platform with + the same runtime modes. + + The example below shows Split mode with two child nodes. + + properties: + compatible: + enum: + - xilinx,r5f + - xilinx,r52 + +# The following properties are mandatory for R5F Core0 in both LockStep and Split +# modes, and are mandatory for R5F Core1 _only_ in Split mode. + + memory-region: + description: | + Phandles to the memory nodes to be associated with the + The reserved memory nodes should be carveout nodes, and + should be defined with a "no-map" property as per the bindings in + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt + minItems: 1 + maxItems: 6 + items: + - description: Region used for dynamic DMA allocations like vrings and + vring buffers + - description: region reserved for firmware image sections + additionalItems: true + + power-domain: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Power node ID that is used to uniquely identify the RPU for Xilinx + Power Management. + +# Optional properties: +# -------------------- +# The following properties are optional properties for each of the R5F cores: + + mboxes: + description: | + Standard property to specify a mailbox + This property is required only if the rpmsg/virtio functionality + is used + + Refer to the zynqmp-ipi-mailbox documentation for client usage of this + property + maxItems: 1 + + mbox-names: + description: | + Refer to the zynqmp-ipi-mailbox documentation for client usage of this + property + items: + - const: tx + - const: rx + + sram: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 4 + items: + maxItems: 1 + description: | + Phandles to one or more reserved on-chip SRAM regions. The regions + should be defined as child nodes of the respective SRAM node, and + should be defined as per the generic bindings in, + Documentation/devicetree/bindings/sram/sram.yaml + + xlnx,rsc-tbl: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: Phandle of carveout + - description: The location of the resource table. It is expected + that the address is within the carveout. If not, then + the resource table physical address will not be stored + and attach will not work. + description: | + Reference to the carveout that has the resource table. The second + argument is the address within the carveout where the resource table + is located. + + required: + - compatible + - power-domain + + unevaluatedProperties: false + +required: + - reg + - compatible + - "#address-cells" + - "#size-cells" + - ranges + +allOf: + - if: + properties: + compatible: + enum: + - xilinx,r5f + then: + required: + - sram + +additionalProperties: false + +examples: + - | + / { + compatible = "xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102", "xlnx,zynqmp"; + #address-cells = <2>; + #size-cells = <2>; + model = "ZynqMP ZCU102 "; + + r5fss@ff9a0000 { + compatible = "xlnx,zynqmp-r5-remoteproc"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x0 0xff9a0000 0x0 0x10000>; + xlnx,cluster-mode = <0>; + + r5f_0 { + compatible = "xilinx,r5f"; + memory-region = <&elf_load0>, + <&rpu0vdev0vring0>, + <&rpu0vdev0vring1>, + <&rpu0vdev0buffer>; + sram = <&tcm_0a>, <&tcm_0b>; + power-domain = <0x7>; + xlnx,rsc-tbl = <&rproc_0_reserved 0x3ed20000>; + }; + r5f_1 { + compatible = "xilinx,r5f"; + memory-region = <&elf_load1>, + <&rpu1vdev0vring0>, + <&rpu1vdev0vring1>, + <&rpu1vdev0buffer>; + sram = <&tcm_1a>, <&tcm_1b>; + power-domain = <0x8>; + }; + + }; + }; + +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml @@ -18,11 +18,26 @@ properties: compatible: - const: xlnx,zynqmp-r5fss + enum: + - xlnx,zynqmp-r5fss + - xlnx,versal-r5fss + - xlnx,versal-net-r52fss + + "#address-cells": + const: 2 + + "#size-cells": + const: 2 + + ranges: + description: | + Standard ranges definition providing address translations for + local R5F TCM address spaces to bus addresses. xlnx,cluster-mode: $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1, 2] + default: 1 description: | The RPU MPCore can operate in split mode (Dual-processor performance), Safety lock-step mode(Both RPU cores execute the same code in lock-step, @@ -36,8 +51,16 @@ 1: lockstep mode (default) 2: single cpu mode + xlnx,tcm-mode: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1] + description: | + Configure RPU TCM + 0: split mode + 1: lockstep mode + patternProperties: - "^r5f-[a-f0-9]+$": + "^r(.*)@[0-9a-f]+$": type: object description: | The RPU is located in the Low Power Domain of the Processor Subsystem. @@ -52,10 +75,22 @@ properties: compatible: - const: xlnx,zynqmp-r5f + enum: + - xlnx,zynqmp-r5f + - xlnx,versal-r5f + - xlnx,versal-net-r52f + + reg: + minItems: 1 + maxItems: 4 + + reg-names: + minItems: 1 + maxItems: 4 power-domains: - maxItems: 1 + minItems: 2 + maxItems: 5 mboxes: minItems: 1 @@ -101,35 +136,235 @@ required: - compatible + - reg + - reg-names - power-domains - unevaluatedProperties: false - required: - compatible + - "#address-cells" + - "#size-cells" + - ranges + +allOf: + - if: + properties: + compatible: + contains: + enum: + - xlnx,versal-net-r52fss + then: + properties: + xlnx,tcm-mode: false + + patternProperties: + "^r52f@[0-9a-f]+$": + type: object + + properties: + reg: + minItems: 1 + items: + - description: ATCM internal memory + - description: BTCM internal memory + - description: CTCM internal memory + + reg-names: + minItems: 1 + items: + - const: atcm0 + - const: btcm0 + - const: ctcm0 + + power-domains: + minItems: 2 + items: + - description: RPU core power domain + - description: ATCM power domain + - description: BTCM power domain + - description: CTCM power domain + + - if: + properties: + compatible: + contains: + enum: + - xlnx,zynqmp-r5fss + - xlnx,versal-r5fss + then: + if: + properties: + xlnx,cluster-mode: + enum: [1, 2] + then: + properties: + xlnx,tcm-mode: + enum: [1] + + patternProperties: + "^r5f@[0-9a-f]+$": + type: object + + properties: + reg: + minItems: 1 + items: + - description: ATCM internal memory + - description: BTCM internal memory + - description: extra ATCM memory in lockstep mode + - description: extra BTCM memory in lockstep mode + + reg-names: + minItems: 1 + items: + - const: atcm0 + - const: btcm0 + - const: atcm1 + - const: btcm1 + + power-domains: + minItems: 2 + items: + - description: RPU core power domain + - description: ATCM power domain + - description: BTCM power domain + - description: second ATCM power domain + - description: second BTCM power domain + + required: + - xlnx,tcm-mode + + else: + properties: + xlnx,tcm-mode: + enum: [0] + + patternProperties: + "^r5f@[0-9a-f]+$": + type: object + + properties: + reg: + minItems: 1 + items: + - description: ATCM internal memory + - description: BTCM internal memory + + reg-names: + minItems: 1 + items: + - const: atcm0 + - const: btcm0 + + power-domains: + minItems: 2 + items: + - description: RPU core power domain + - description: ATCM power domain + - description: BTCM power domain + + required: + - xlnx,tcm-mode additionalProperties: false examples: - | - remoteproc { - compatible = "xlnx,zynqmp-r5fss"; - xlnx,cluster-mode = <1>; - - r5f-0 { - compatible = "xlnx,zynqmp-r5f"; - power-domains = <&zynqmp_firmware 0x7>; - memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; - mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; - mbox-names = "tx", "rx"; + #include + + // Split mode configuration + soc { + #address-cells = <2>; + #size-cells = <2>; + + remoteproc@ffe00000 { + compatible = "xlnx,zynqmp-r5fss"; + xlnx,cluster-mode = <0>; + xlnx,tcm-mode = <0>; + + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>, + <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>, + <0x1 0x0 0x0 0xffe90000 0x0 0x10000>, + <0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>; + + r5f@0 { + compatible = "xlnx,zynqmp-r5f"; + reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>; + reg-names = "atcm0", "btcm0"; + power-domains = <&zynqmp_firmware PD_RPU_0>, + <&zynqmp_firmware PD_R5_0_ATCM>, + <&zynqmp_firmware PD_R5_0_BTCM>; + memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, + <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; + mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; + mbox-names = "tx", "rx"; + }; + + r5f@1 { + compatible = "xlnx,zynqmp-r5f"; + reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>; + reg-names = "atcm0", "btcm0"; + power-domains = <&zynqmp_firmware PD_RPU_1>, + <&zynqmp_firmware PD_R5_1_ATCM>, + <&zynqmp_firmware PD_R5_1_BTCM>; + memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, + <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; + mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; + mbox-names = "tx", "rx"; + }; }; + }; - r5f-1 { - compatible = "xlnx,zynqmp-r5f"; - power-domains = <&zynqmp_firmware 0x8>; - memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; - mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; - mbox-names = "tx", "rx"; + - | + //Lockstep configuration + soc { + #address-cells = <2>; + #size-cells = <2>; + + remoteproc@ffe00000 { + compatible = "xlnx,zynqmp-r5fss"; + xlnx,cluster-mode = <1>; + xlnx,tcm-mode = <1>; + + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>, + <0x0 0x20000 0x0 0xffe20000 0x0 0x10000>, + <0x0 0x10000 0x0 0xffe10000 0x0 0x10000>, + <0x0 0x30000 0x0 0xffe30000 0x0 0x10000>; + + r5f@0 { + compatible = "xlnx,zynqmp-r5f"; + reg = <0x0 0x0 0x0 0x10000>, + <0x0 0x20000 0x0 0x10000>, + <0x0 0x10000 0x0 0x10000>, + <0x0 0x30000 0x0 0x10000>; + reg-names = "atcm0", "btcm0", "atcm1", "btcm1"; + power-domains = <&zynqmp_firmware PD_RPU_0>, + <&zynqmp_firmware PD_R5_0_ATCM>, + <&zynqmp_firmware PD_R5_0_BTCM>, + <&zynqmp_firmware PD_R5_1_ATCM>, + <&zynqmp_firmware PD_R5_1_BTCM>; + memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, + <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; + mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; + mbox-names = "tx", "rx"; + }; + + r5f@1 { + compatible = "xlnx,zynqmp-r5f"; + reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>; + reg-names = "atcm0", "btcm0"; + power-domains = <&zynqmp_firmware PD_RPU_1>, + <&zynqmp_firmware PD_R5_1_ATCM>, + <&zynqmp_firmware PD_R5_1_BTCM>; + memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, + <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; + mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; + mbox-names = "tx", "rx"; + }; }; }; ... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/serial/cdns,uart.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/serial/cdns,uart.yaml @@ -46,6 +46,9 @@ power-domains: maxItems: 1 + resets: + maxItems: 1 + required: - compatible - reg @@ -55,6 +58,7 @@ allOf: - $ref: serial.yaml# + - $ref: rs485.yaml# - if: properties: compatible: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/serial/xlnx,opb-uartlite.yaml @@ -15,6 +15,7 @@ enum: - xlnx,xps-uartlite-1.00.a - xlnx,opb-uartlite-1.00.b + - xlnx,axi-uartlite-rs485 reg: maxItems: 1 --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/soc/rockchip/grf.yaml @@ -165,6 +165,7 @@ unevaluatedProperties: false pcie-phy: + type: object description: Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/soc/xilinx/xilinx.yaml @@ -10,7 +10,7 @@ - Michal Simek description: | - Xilinx boards with Zynq-7000 SOC or Zynq UltraScale+ MPSoC + Xilinx boards with Zynq-7000 SOC or Zynq UltraScale+ MPSoC or Versal or Versal NET properties: $nodename: @@ -63,7 +63,10 @@ - description: Xilinx evaluation board zcu1275 items: - - const: xlnx,zynqmp-zcu1275-revA + - enum: + - xlnx,zynqmp-zcu1275-revA + - xlnx,zynqmp-zcu1275-revB + - xlnx,zynqmp-zcu1275-rev1.0 - const: xlnx,zynqmp-zcu1275 - const: xlnx,zynqmp @@ -81,6 +84,14 @@ - const: xlnx,zynqmp-zcu100 - const: xlnx,zynqmp + - description: Xilinx ZynqMP based System Controller + items: + - enum: + - xlnx,zynqmp-sc-revB + - xlnx,zynqmp-sc-revC + - const: xlnx,zynqmp-sc + - const: xlnx,zynqmp + - description: Xilinx evaluation board zcu102 items: - enum: @@ -116,6 +127,29 @@ - const: xlnx,zynqmp-zcu111 - const: xlnx,zynqmp + - description: Xilinx evaluation board zcu208 + items: + - enum: + - xlnx,zynqmp-zcu208-revA + - xlnx,zynqmp-zcu208-rev1.0 + - const: xlnx,zynqmp-zcu208 + - const: xlnx,zynqmp + + - description: Xilinx evaluation board zcu216 + items: + - enum: + - xlnx,zynqmp-zcu216-revA + - xlnx,zynqmp-zcu216-rev1.0 + - const: xlnx,zynqmp-zcu216 + - const: xlnx,zynqmp + + - description: Xilinx evaluation board zcu1285 + items: + - enum: + - xlnx,zynqmp-zcu1285-revA + - xlnx,zynqmp-zcu1285-rev1.0 + - const: xlnx,zynqmp-zcu1285 + - description: Xilinx Kria SOMs items: - const: xlnx,zynqmp-sm-k26-rev1 @@ -132,6 +166,46 @@ - const: xlnx,zynqmp-smk-k26 - const: xlnx,zynqmp + - description: Xilinx Versal NET b2197 (Tenzing2) + items: + - const: xlnx,versal-net-vn-p-b2197-00-revA + - const: xlnx,versal-net-vn-p-b2197-00 + - const: xlnx,versal-net + + - description: Xilinx Kria SOM KV260 revA/Y/Z + minItems: 3 + items: + enum: + - xlnx,zynqmp-sk-kv260-revA + - xlnx,zynqmp-sk-kv260-revY + - xlnx,zynqmp-sk-kv260-revZ + - xlnx,zynqmp-sk-kv260 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp-sk-kv260-revA + - contains: + const: xlnx,zynqmp-sk-kv260 + - contains: + const: xlnx,zynqmp + + - description: Xilinx Kria SOM KV260 rev2/1/B + minItems: 3 + items: + enum: + - xlnx,zynqmp-sk-kv260-rev2 + - xlnx,zynqmp-sk-kv260-rev1 + - xlnx,zynqmp-sk-kv260-revB + - xlnx,zynqmp-sk-kv260 + - xlnx,zynqmp + allOf: + - contains: + const: xlnx,zynqmp-sk-kv260-revB + - contains: + const: xlnx,zynqmp-sk-kv260 + - contains: + const: xlnx,zynqmp + - description: AMD MicroBlaze V (QEMU) items: - const: qemu,mbv --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/xilinx/xlnx,ai-engine.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx AI Engine + +maintainers: + - Wendy Liang + +description: |+ + The Xilinx AI Engine is a tile processor with many cores (up to 400) that + can run in parallel. The data routing between cores is configured through + internal switches, and shim tiles interface with external interconnect, such + as memory or PL. One AI engine device can have multiple apertures, each + has its own address space and interrupt. At runtime application can create + multiple partitions within an aperture which are groups of columns of AI + engine tiles. Each AI engine partition is the minimum resetable unit for an + AI engine application. + +properties: + compatible: + enum: + - xlnx,ai-engine-v2.0 + - xlnx,ai-engine-v1.0 # deprecated + + reg: + deprecated: true + description: | + Physical base address and length of the device registers. + The AI engine address space assigned to Linux is defined by Xilinx + platform design tool. + + '#address-cells': + enum: [2] + description: | + size of cell to describe AI engine range of tiles address. + It is the location of the starting tile of the range. + As the AI engine tiles are 2D array, the location of a tile + is presented as (column, row), the address cell is 2. + + '#size-cells': + enum: [2] + description: | + size of cell to describe AI engine range of tiles size. + As the AI engine tiles are 2D array, the size cell is 2. + + interrupts: + deprecated: true + maxItems: 3 + + interrupt-names: + deprecated: true + description: | + Should be "interrupt1", "interrupt2" or "interrupt3". + + ranges: true + + xlnx,aie-gen: + $ref: /schemas/types.yaml#/definitions/uint8 + description: | + hardware generation of AI engine device. E.g. the current values supported + are 1 and 2, it will be presented as <0x1> or <0x2> + + xlnx,shim-rows: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + start row and the number of rows of SHIM tiles of the AI engine device + + xlnx,core-rows: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + start row and the number of rows of core tiles of the AI engine device + + xlnx,mem-rows: + $ref: /schemas/types.yaml#/definitions/uint8-array + description: | + start row and the number of rows of memory tiles of the AI engine device + +required: + - compatible + - '#address-cells' + - '#size-cells' + - ranges + - power-domains + - xlnx,aie-gen + - xlnx,shim-rows + - xlnx,core-rows + - xlnx,mem-rows + +patternProperties: + "^aperture@[0-9]+$": + type: object + description: | + AI engine aperture which is a group of column based tiles of the + AI engine device. Each AI engine apertures isolated from the + other AI engine apertures. An AI engine aperture is defined by + Xilinx platform design tools. + + properties: + reg: + description: | + Physical base address and length of the aperture registers. + The AI engine address space assigned to Linux is defined by Xilinx + platform design tool. + + xlnx,columns: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + It describes the location of the aperture. It specifies the start + column and the number of columns. E.g. an aperture starts from + column 0 and there are 50 columns, it will be presented as <0 50>. + + interrupts: + maxItems: 3 + + interrupt-names: + description: | + Should be "interrupt1", "interrupt2" or "interrupt3". + + xlnx,node-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + AI engine aperture node ID, which is defined by Xilinx platform design + tool to identify the AI engine aperture in the firmware. + + required: + - reg + - xlnx,columns + - xlnx,node-id + + "^partition[0-9]@[0-9]+$": + deprecated: true + type: object + description: | + AI engine partition which is a group of column based tiles of the AI + engine device. Each AI engine partition is isolated from the other + AI engine partitions. An AI engine partition is defined by Xilinx + platform design tools. + AI engine partition driver will create a FPGA bridge when probes the + AI engine partition. The AI engine SHIM row of the partition is the + bridge to connect AI engine partition, FPGA and PS. + + properties: + reg: + description: | + It describes the group of tiles of the AI engine partition. It needs + to include the SHIM row. The format is defined by the parent AI engine + device node's '#address-cells' and '#size-cells' properties. e.g. a v1 + AI engine device has 2D tiles array, the first row is SHIM row. A + partition which has 50 columns and 8 rows of core tiles and 1 row of + SHIM tiles will be presented as <0 0 50 9>. + + label: + maxItems: 1 + + xlnx,partition-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + AI engine partition ID, which is defined by Xilinx platform design + tool to identify the AI engine partition in the system. + + required: + - reg + - xlnx,partition-id + +additionalProperties: true + +examples: + - | + #include + bus { + #address-cells = <2>; + #size-cells = <2>; + ai_engine: ai-engine { + compatible = "xlnx,ai-engine-v2.0"; + xlnx,aie-gen = /bits/ 8 <0x1>; + xlnx,shim-rows = /bits/ 8 <0 1>; + xlnx,core-rows = /bits/ 8 <1 8>; + xlnx,mem-rows = /bits/ 8 <0 0>; + power-domains = <&versal_firmware PM_DEV_AI>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + aperture0: aperture@0 { + /* 50 columns and 8 core tile rows + 1 SHIM row */ + reg = <0x200 0x0 0x1 0x0>; + xlnx,columns = <0 50>; + xlnx,node-id = <1>; + interrupt-parent = <&gic>; + interrupts = <0x0 0x94 0x4>, + <0x0 0x95 0x4>, + <0x0 0x96 0x4>; + interrupt-names = "interrupt1", "interrupt2", "interrupt3"; + }; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/soc/xilinx/xlnx,ai_engine.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/soc/xilinx/xlnx,ai_engine.txt @@ -0,0 +1,28 @@ +Xilinx AI Engine +---------------- + +The Xilinx AI Engine is a tile processor with many cores (up to 400) that +can run in parallel. The data routing between cores is configured through +internal switches, and shim tiles interface with external interconnect, such +as memory or PL. + +Required properties: + +- compatible: Must be "xlnx,ai_engine". +- reg: Physical base address and length of the registers set for the device. +- interrupt-parent: the phandle to the interrupt controller. +- interrupts: the interrupt numbers. +- interrupt-names: Should be "interrupt0", "interrupt1", "interrupt2" or + "interrupt3". + +Example: + + ai_engine@20000000000 { + compatible = "xlnx,ai_engine"; + reg = <0x200 0x0 0x1 0x0>; + interrupt-parent = <&gic>; + interrupts = <0x0 0x94 0x1>, + <0x0 0x95 0x1>, + <0x0 0x96 0x1>; + interrupt-names = "interrupt1", "interrupt2", "interrupt3"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/rt5645.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/rt5645.txt @@ -20,6 +20,11 @@ a GPIO spec for the external headphone detect pin. If jd-mode = 0, we will get the JD status by getting the value of hp-detect-gpios. +- cbj-sleeve-gpios: + a GPIO spec to control the external combo jack circuit to tie the sleeve/ring2 + contacts to the ground or floating. It could avoid some electric noise from the + active speaker jacks. + - realtek,in2-differential Boolean. Indicate MIC2 input are differential, rather than single-ended. @@ -68,6 +73,7 @@ compatible = "realtek,rt5650"; reg = <0x1a>; hp-detect-gpios = <&gpio 19 0>; + cbj-sleeve-gpios = <&gpio 20 0>; interrupt-parent = <&gpio>; interrupts = <7 IRQ_TYPE_EDGE_FALLING>; realtek,dmic-en = "true"; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt @@ -1,6 +1,6 @@ Device-Tree bindings for Xilinx PL audio formatter -The IP core supports DMA, data formatting(AES<->PCM conversion) +The IP core supports DMA, data formatting(packing, conversion) of audio samples. Required properties: @@ -13,8 +13,21 @@ - interrupts-parent: Phandle for interrupt controller. - interrupts: List of Interrupt numbers. - reg: Base address and size of the IP core instance. + - xlnx,tx: connected audio sink node. + Should be one of below supported nodes: + 1. HDMI video Tx output + 2. I2S transmitter + 3. UHDSDI audio embed + Only those nodes were supported in sound card driver + + - xlnx,rx: connected audio source node. + Should be one of below supported nodes: + 1. HDMI video Rx input + 2. I2S receiver + 3. UHDSDI audio extract + Only those nodes were supported in sound card driver - clock-names: List of input clocks. - Required elements: "s_axi_lite_aclk", "aud_mclk" + Required elements: "s_axi_lite_aclk", "m_axis_mm2s_aclk", "aud_mclk", "s_axis_s2mm_aclk" - clocks: Input clock specifier. Refer to common clock bindings. Example: @@ -24,6 +37,8 @@ interrupt-parent = <&gic>; interrupts = <0 104 4>, <0 105 4>; reg = <0x0 0x80010000 0x0 0x1000>; - clock-names = "s_axi_lite_aclk", "aud_mclk"; - clocks = <&clk 71>, <&clk_wiz_1 0>; + xlnx,tx = <&i2s_transmitter>; + xlnx,rx = <&i2s_receiver>; + clock-names = "s_axi_lite_aclk", "m_axis_mm2s_aclk", "aud_mclk", "s_axis_s2mm_aclk"; + clocks = <&clk 71>, <&audio_ss_0_clk_wiz_0 0>, <&audio_ss_0_clk_wiz_0 0>, <&clk 71>; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,dp-snd-card.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,dp-snd-card.txt @@ -0,0 +1,17 @@ +Device-Tree bindings for Xilinx ZynqMP DisplayPort Audio Card + +The card driver integrates codec and pcm components and represents as a single +audio device. + +Required properties: + - compatible: Should be "xlnx,dp-snd-card". + - xlnx,dp-snd-pcm: phandle(s) to the ZynqMP DP PCM node. + - xlnx,dp-snd-codec: phandle to the ZynqMP DP card node. + +Example: + + xlnx_dp_snd_card: dp_snd_card { + compatible = "xlnx,dp-snd-card"; + xlnx,dp-snd-pcm = <&xlnx_dp_snd_pcm0>, <&xlnx_dp_snd_pcm1>; + xlnx,dp-snd-codec = <&xlnx_dp_snd_codec0>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,dp-snd-codec.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,dp-snd-codec.txt @@ -0,0 +1,18 @@ +Device-Tree bindings for Xilinx ZynqMP DisplayPort Codec + +The codec driver handles the audio clock and format management. + +Required properties: + - compatible: Should be "xlnx,dp-snd-codec". + - clocks: The phandle for the audio clock. The audio clock should be + configured to the correct audio clock rate, which should be one of + (44100 * 512) or (48000 * 512). + - clock-names: The identification string should be "aud_clk". + +Example: + + xlnx_dp_snd_codec0: dp_snd_codec0 { + compatible = "xlnx,dp-snd-codec"; + clocks = <&dp_aud_clk>; + clock-names = "aud_clk"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,dp-snd-pcm.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,dp-snd-pcm.txt @@ -0,0 +1,18 @@ +Device-Tree bindings for Xilinx ZynqMP DisplayPort PCM + +The DPDMA driver of ZynqMP DisplayPort subsystem is based on DMA engine, +and the DP PCM driver is based on snd dmaengine helpers. + +Required properties: + - compatible: Should be "xlnx,dp-snd-pcm" or "xlnx,dp-snd-pcm0" or "xlnx,dp-snd-pcm1". + - dmas: the phandle list of DMA specifiers. The dma channel ID should be one + of 4 for audio0 channel or 5 for audio1 channel. + - dma-names: the indentifier strings for DMAs. The value should be "tx". + +Example: + + xlnx_dp_snd_pcm0: dp_snd_pcm0 { + compatible = "xlnx,dp-snd-pcm0"; + dmas = <&xlnx_dpdma 4>; + dma-names = "tx"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,i2s.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,i2s.txt @@ -11,18 +11,31 @@ - xlnx,dwidth: sample data width. Can be any of 16, 24. - xlnx,num-channels: Number of I2S streams. Can be any of 1, 2, 3, 4. supported channels = 2 * xlnx,num-channels + - xlnx,snd-pcm: reference to audio formatter block + - clock-names: List of input clocks. + Required elements for I2S Tx: "s_axi_ctrl_aclk", "aud_mclk", "s_axis_aud_aclk". + Required elements for I2S Rx: "s_axi_ctrl_aclk", "aud_mclk", "m_axis_aud_aclk". + - clocks: Input clock specifier. Refer to common clock bindings. Example: i2s_receiver@a0080000 { compatible = "xlnx,i2s-receiver-1.0"; + clock-names = "s_axi_ctrl_aclk", "aud_mclk", "m_axis_aud_aclk"; + clocks = <&clk 71>, <&audio_ss_0_clk_wiz_0 0>, <&clk 71>; reg = <0x0 0xa0080000 0x0 0x10000>; xlnx,dwidth = <0x18>; xlnx,num-channels = <1>; + xlnx,snd-pcm = <&audio_ss_0_audio_formatter_0>; }; i2s_transmitter@a0090000 { compatible = "xlnx,i2s-transmitter-1.0"; + clock-names = "s_axi_ctrl_aclk", "aud_mclk", "s_axis_aud_aclk"; + clocks = <&clk 71>, <&audio_ss_0_clk_wiz_0 0>, <&audio_ss_0_clk_wiz_0 0>; reg = <0x0 0xa0090000 0x0 0x10000>; xlnx,dwidth = <0x18>; xlnx,num-channels = <1>; + xlnx,snd-pcm = <&audio_ss_0_audio_formatter_0>; }; + Documentation of "audio_ss_0_audio_formatter_0" node is located + at Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,spdif.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,spdif.txt @@ -1,28 +1,27 @@ -Device-Tree bindings for Xilinx SPDIF IP +Device-Tree bindings for Xilinx SPDIF PL IP -The IP supports playback and capture of SPDIF audio +The IP supports SPDIF based playback and capture audio Required properties: - compatible: "xlnx,spdif-2.0" - clock-names: List of input clocks. - Required elements: "s_axi_aclk", "aud_clk_i" + Required elements for SPDIF Tx: "aud_clk_i", "s_axi_aclk", "s_axis_aclk". + Required elements for SPDIF Rx: "aud_clk_i", "s_axi_aclk", "m_axis_aclk". - clocks: Input clock specifier. Refer to common clock bindings. - reg: Base address and address length of the IP core instance. - interrupts-parent: Phandle for interrupt controller. - interrupts: List of Interrupt numbers. - - xlnx,spdif-mode: 0 :- receiver mode - 1 :- transmitter mode - - xlnx,aud_clk_i: input audio clock value. + - xlnx,spdif-mode: 0 :- receiver mode ; 1 :- transmitter mode + - xlnx,snd-pcm: phandle to audio formatter node -Example: +Example - SPDIF Rx: spdif_0: spdif@80010000 { - clock-names = "aud_clk_i", "s_axi_aclk"; - clocks = <&misc_clk_0>, <&clk 71>; + clock-names = "aud_clk_i", "s_axi_aclk", "m_axis_aclk"; + clocks = <&si570_1>, <&clk 71>, <&clk 71>; compatible = "xlnx,spdif-2.0"; - interrupt-names = "spdif_interrupt"; interrupt-parent = <&gic>; interrupts = <0 91 4>; reg = <0x0 0x80010000 0x0 0x10000>; xlnx,spdif-mode = <1>; - xlnx,aud_clk_i = <49152913>; + xlnx,snd-pcm = <&audio_formatter_0>; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/sound/xlnx,v-uhdsdi-audio.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/sound/xlnx,v-uhdsdi-audio.txt @@ -0,0 +1,60 @@ +Device-Tree bindings for Xilinx SDI audio + +The IP core supports embed/extract of audio in SDI Tx and Rx +protocol respectively. Reference to PG: +https://www.xilinx.com/support/documentation/ip_documentation/v_uhdsdi_audio/v1_0/pg309-v-uhdsdi-audio.pdf + +Required properties: + - compatible: Should be one of: + "xlnx,v-uhdsdi-audio-2.0" + "xlnx,v-uhdsdi-audio-1.0" + Note: v1.0 (xlnx,v-uhdsdi-audio-1.0) is deprecated + and driver no longer supports it. Mandatory to upgrade to v2.0 + - interrupts: Interrupt number. + - interrupts-parent: phandle for interrupt controller. + - reg: Base address and size of the IP core instance. + - xlnx,snd-pcm: reference to audio formatter block + - clock-names: List of input clocks. + Required elements for SDI Embed: "s_axi_aclk", "s_axis_clk", "sdi_embed_clk". + Required elements for SDI Extract: "s_axi_aclk", "sdi_extract_clk", "m_axis_clk". + - clocks: Input clock specifier. Refer to common clock bindings. + +SDI embed contains a output port to remote endpoint of SDI video Tx node. +This pipeline should be described using the DT bindings defined in +Documentation/devicetree/bindings/graph.txt + +Example: + + audio_ss_0_v_uhdsdi_audio_extract_0: v_uhdsdi_audio@80080000 { + compatible = "xlnx,v-uhdsdi-audio-2.0"; + clock-names = "s_axi_aclk", "sdi_extract_clk", "m_axis_clk"; + clocks = <&misc_clk_0>, <&misc_clk_1>, <&misc_clk_0>; + interrupt-names = "interrupt"; + interrupt-parent = <&gic>; + interrupts = <0 106 4>; + reg = <0x0 0x80080000 0x0 0x10000>; + xlnx,snd-pcm = <&audio_ss_0_audio_formatter_0>; + }; + + audio_ss_0_v_uhdsdi_audio_embed_0: v_uhdsdi_audio@80090000 { + compatible = "xlnx,v-uhdsdi-audio-2.0"; + clock-names = "s_axi_aclk", "s_axis_clk", "sdi_embed_clk"; + clocks = <&misc_clk_0>, <&misc_clk_0>, <&misc_clk_1>; + interrupt-names = "interrupt"; + interrupt-parent = <&gic>; + interrupts = <0 107 4>; + reg = <0x0 0x80090000 0x0 0x10000>; + xlnx,snd-pcm = <&audio_ss_0_audio_formatter_0>; + sdi_av_port: port@0 { + reg = <0>; + sditx_audio_embed_src: endpoint { + remote-endpoint = <&sdi_audio_sink_port>; + }; + }; + }; + + Node 'v_smpte_uhdsdi_tx_ss' is documented in SDI Tx video bindings, + located at Documentation/devicetree/bindings/display/xlnx/xlnx,sdi-tx.txt. + + Node 'audio_ss_0_audio_formatter_0' node is documented + at Documentation/devicetree/bindings/sound/xlnx,audio-formatter.txt --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/spi/spi-controller.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/spi/spi-controller.yaml @@ -161,4 +161,12 @@ reg = <2>, <3>; stacked-memories = /bits/ 64 <0x10000000 0x10000000>; }; + + flash@5 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <50000000>; + reg = <5>; + multi-die; + }; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml @@ -118,6 +118,11 @@ Only for STM32H7, (Master Inter-Data Idleness) minimum time delay in nanoseconds inserted between two consecutive data frames. + multi-die: + $ref: /schemas/types.yaml#/definitions/flag + description: + The device consists of multiple memory die. + # The controller specific properties go here. allOf: - $ref: arm,pl022-peripheral-props.yaml# --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/spi/spi-zynqmp-qspi.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/spi/spi-zynqmp-qspi.yaml @@ -37,6 +37,12 @@ power-domains: maxItems: 1 + has-io-mode: + $ref: /schemas/types.yaml#/definitions/flag + description: + Describes the controller operating mode. + If exists controller will operate in IO + mode else DMA mode. required: - compatible @@ -62,5 +68,6 @@ interrupt-parent = <&gic>; reg = <0x0 0xff0f0000 0x0 0x1000>, <0x0 0xc0000000 0x0 0x8000000>; + has-io-mode; }; }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml @@ -14,7 +14,7 @@ It is a MIPI System Power Management (SPMI) controller. The PMIC part is provided by - ./Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml. + Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml. allOf: - $ref: spmi.yaml# @@ -48,7 +48,7 @@ PMIC properties, which are specific to the used SPMI PMIC device(s). When used in combination with HiSilicon 6421v600, the properties are documented at - drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml. + Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml unevaluatedProperties: false --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/staging/net/xilinx-tsn-ethernet.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/staging/net/xilinx-tsn-ethernet.txt @@ -0,0 +1,54 @@ +Xilinx TSN (time sensitive networking) TEMAC axi ethernet driver (xilinx_axienet) +----------------------------------------------------------------------- + +Required properties: +- compatible : Should be "xlnx,tsn-ethernet-1.00.a". +- reg : Physical base address and size of the TSN registers map. +- interrupts : Property with a value describing the interrupt + number. +- interrupts-names : Property denotes the interrupt names. +- interrupt-parent : Must be core interrupt controller. +- phy-handle : See ethernet.txt file [1]. +- local-mac-address : See ethernet.txt file [1]. +- phy-mode : see ethernet.txt file [1]. + +Optional properties: +- xlnx,tsn : Denotes a ethernet with TSN capabilities. +- xlnx,tsn-slave : Denotes a TSN slave port. +- xlnx,txcsum : Tx checksum mode (Full, Partial and None). +- xlnx,rxcsum : Rx checksum mode (Full, Partial and None). +- xlnx,phy-type : Xilinx phy device type. See xilinx-phy.txt [2]. +- xlnx,eth-hasnobuf : Used when 1G MAC is configured in non-processor mode. +- xlnx,num-queue : Number of queue supported in current design, range is + 2 to 5 and default value is 5. +- xlnx,num-tc : Number of traffic class supported in current design, + range is 2,3 and default value is 3. It denotes + the traffic classes based on VLAN-PCP value. +- xlnx,qbv-addr : Denotes mac scheduler physical base address. +- xlnx,qbv-size : Denotes mac scheduler address space size. + +[1] Documentation/devicetree/bindings/net/ethernet.txt +[2] Documentation/devicetree/bindings/net/xilinx-phy.txt + +Example: + + tsn_emac_0: tsn_mac@80040000 { + compatible = "xlnx,tsn-ethernet-1.00.a"; + interrupt-parent = <&gic>; + interrupts = <0 104 4 0 106 4 0 91 4 0 110 4>; + interrupt-names = "interrupt_ptp_rx_1", "interrupt_ptp_tx_1", "mac_irq_1", "interrupt_ptp_timer"; + local-mac-address = [ 00 0A 35 00 01 0e ]; + phy-mode = "rgmii"; + reg = <0x0 0x80040000 0x0 0x14000>; + tsn,endpoint = <&tsn_ep>; + xlnx,tsn; + xlnx,tsn-slave; + xlnx,phy-type = <0x3>; + xlnx,eth-hasnobuf; + xlnx,num-queue = <0x2>; + xlnx,num-tc = <0x3>; + xlnx,qbv-addr = <0x80054000>; + xlnx,qbv-size = <0x2000>; + xlnx,txsum = <0>; + xlnx,rxsum = <0>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/staging/net/xilinx_tsn.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/staging/net/xilinx_tsn.txt @@ -0,0 +1,17 @@ +Xilinx TSN (time sensitive networking) IP driver (xilinx_tsn_ip) +----------------------------------------------------------------------- + +Required properties: +- compatible : Should be one of "xlnx,tsn-endpoint-ethernet-mac-1.0", + "xlnx,tsn-endpoint-ethernet-mac-2.0" for TSN. +- reg : Physical base address and size of the TSN registers map. +- ranges : Specifies child address ranges of TSN IP subsystem including + TEMACs, endpoint and switch. Leave this property as empty + because parent node has the same mapping as all the child nodes. +Example: + + tsn_endpoint_ip_0: tsn_endpoint_ip_0 { + compatible = "xlnx,tsn-endpoint-ethernet-mac-2.0"; + reg = <0x0 0x80040000 0x0 0x40000>; + ranges; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/staging/net/xilinx_tsn_ep.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/staging/net/xilinx_tsn_ep.txt @@ -0,0 +1,54 @@ +Xilinx TSN (time sensitive networking) EndPoint Driver (xilinx_tsn_ep) +------------------------------------------------------------------------------- + +Required properties: +- compatible : Should be "xlnx,tsn-ep" +- reg : Physical base address and size of the TSN Endpoint + registers map +- interrupts : Property with a value describing the interrupt +- interrupts-names : Property denotes the interrupt names. +- interrupt-parent : Must be core interrupt controller. + +Optional properties: +- xlnx,num-tc : Number of traffic class supported in current design, + range is 2,3 and default value is 3. It denotes + the traffic classes based on VLAN-PCP value. +- xlnx,channel-ids : Queue Identifier associated with the MCDMA Channel, range + is Tx: "1 to 2" and Rx: "2 to 5", default value is "1 to 5". +- xlnx,eth-hasnobuf : Used when 1G MAC is configured in non processor mode. +- axistream-connected-rx : Reference to another node which contains the + resources for the MCDMA controller used by + this device. The MCDMA related resources + (registers and interrupts) will be used from + this node. + +Optional TADMA properties: +- xlnx,num-buffers-per-stream : Number of TADMA buffers per stream in design. Default is 64. +- xlnx,num-streams : Number of streams. Default is 8. +- xlnx,num-fetch-entries : Maximum number of entries that can be programmed to be + fetched by TADMA. Default is 8. +- axistream-connected-tx : Reference to another node which contains the + resources for the TADMA controller used by + this device. The TADMA-related resources + (registers and interrupts) will be used from + this node. + +Optional MCDMA properties: +- xlnx,num-mm2s-channels : Number of MM2S(read) channels in MCDMA +- xlnx,num-s2mm-channels : Number of S2MM(write) channels in MCDMA + +[1] Documentation/devicetree/bindings/net/ethernet.txt + +Example: + + tsn_ep: tsn_ep@80056000 { + compatible = "xlnx,tsn-ep"; + reg = <0x0 0x80056000 0x0 0xA000>; + xlnx,num-tc = <0x3>; + interrupt-names = "tsn_ep_scheduler_irq"; + interrupt-parent = <&gic>; + interrupts = <0 111 4>; + local-mac-address = [00 0A 35 00 01 10]; + xlnx,channel-ids = "1","2","3","4","5"; + xlnx,eth-hasnobuf ; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/staging/net/xilinx_tsn_ep_ex.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/staging/net/xilinx_tsn_ep_ex.txt @@ -0,0 +1,31 @@ +Xilinx TSN (time sensitive networking) Extended EndPoint Driver (xilinx_tsn_ep_ex) +------------------------------------------------------------------------------- + +Required properties: +- compatible : Should be "xlnx,tsn-ex-ep" +- reg : Physical base address and size of the TSN Endpoint + registers map +- local-mac-address : See ethernet.txt [1]. + +Optional properties: +- packet-switch : set to 1 when packet switching on ex-ep is + enabled in the design. + This property deprecated. + To identify the packet switching feature is enabled + or not in the design, please use the + xlnx, packet-switch property from the switch node + instead of packet-switch property. +- tsn,endpoint : This is a handle to the endpoint node. + The necessary ep resource details are obtained + from this reference. + +[1] Documentation/devicetree/bindings/net/ethernet.txt + +Example: + + tsn_ep_ex: tsn_ep_ex@80056000 { + compatible = "xlnx,tsn-ex-ep"; + reg = <0x0 0x80056000 0x0 0xA000>; + local-mac-address = [00 0A 35 00 01 20]; + tsn,endpoint = <&tsn_ep>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/staging/net/xilinx_tsn_switch.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/staging/net/xilinx_tsn_switch.txt @@ -0,0 +1,27 @@ +Xilinx TSN (time sensitive networking) Switch Driver (xilinx_tsn_switch) +----------------------------------------------------------------------------- + +Required properties: +- compatible : Should be "xlnx,tsn-switch" +- reg : Physical base address and size of the TSN registers map. +- xlnx,num-ports : Number of network ports in subsystems. For ex., for an + EP + Switch system to two TEMACs, this value should be 3 + (ep, temac1 and temac 2). + +Optional properties: +- xlnx,num-tc : Number of traffic class supported in current design, + range is 2,3 and default value is 3. It denotes + the traffic classes based on VLAN-PCP value. +- xlnx,has-hwaddr-learning : Denotes hardware address learning support +- xlnx,has-inband-mgmt-tag : Denotes inband management support +- xlnx,packet-switch : Denotes packet switching support. + +Example: + + epswitch: tsn_switch@80078000 { + compatible = "xlnx,tsn-switch"; + reg = <0x0 0x80078000 0x0 0x4000>; + xlnx,num-tc = <0x3>; + xlnx,has-hwaddr-learning ; + xlnx,has-inband-mgmt-tag ; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml @@ -18,13 +18,15 @@ oneOf: - enum: - loongson,ls2k1000-thermal + - loongson,ls2k2000-thermal - items: - enum: - - loongson,ls2k2000-thermal + - loongson,ls2k0500-thermal - const: loongson,ls2k1000-thermal reg: - maxItems: 1 + minItems: 1 + maxItems: 2 interrupts: maxItems: 1 @@ -38,6 +40,24 @@ - interrupts - '#thermal-sensor-cells' +if: + properties: + compatible: + contains: + enum: + - loongson,ls2k2000-thermal + +then: + properties: + reg: + minItems: 2 + maxItems: 2 + +else: + properties: + reg: + maxItems: 1 + unevaluatedProperties: false examples: --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2024 Advanced Micro Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/xlnx,versal-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Versal Thermal + +maintainers: + - Salih Erim + +description: + Versal Thermal uses Versal Sysmon hardware for temperature reading + It works as sensor interface to be defined in thermal zones. + IIO binding channel through Sysmon required to use as temperature + sensor. It uses sysmon-temp-channel mapped in the Sysmon driver. + name to expose temperature information. + Exposed temperature value is converted to millicelcius scale. + +properties: + compatible: + const: xlnx,versal-thermal + + '#thermal-sensor-cells': + const: 0 + + io-channels: + maxItems: 1 + + io-channel-names: + const: sysmon-temp-channel + +required: + - compatible + - '#thermal-sensor-cells' + - io-channels + - io-channel-names + +additionalProperties: false + +examples: + - | + versal-thermal-sensor { + compatible = "xlnx,versal-thermal"; + #thermal-sensor-cells = <0>; + io-channels = <&sysmon0>; + io-channel-names = "sysmon-temp-channel"; + }; +... --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/timer/cdns,ttc.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/timer/cdns,ttc.yaml @@ -32,12 +32,23 @@ description: | Bit width of the timer, necessary if not 16. + "#pwm-cells": + const: 3 + required: - compatible - reg - - interrupts - clocks +allOf: + - if: + not: + required: + - "#pwm-cells" + then: + required: + - interrupts + additionalProperties: false examples: @@ -50,3 +61,12 @@ clocks = <&cpu_clk 3>; timer-width = <32>; }; + + - | + pwm: pwm@f8002000 { + compatible = "cdns,ttc"; + reg = <0xf8002000 0x1000>; + clocks = <&cpu_clk 3>; + timer-width = <32>; + #pwm-cells = <3>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/ufs/amd,versal2-ufs.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/ufs/amd,versal2-ufs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: AMD Versal Gen 2 UFS Host Controller + +maintainers: + - Sai Krishna Potthuri + +allOf: + - $ref: ufs-common.yaml + +properties: + compatible: + const: amd,versal2-ufs + + reg: + maxItems: 1 + + clocks: + maxItems: 3 + + clock-names: + items: + - const: core_clk + - const: phy_clk + - const: ref_clk + + resets: + minItems: 2 + maxItems: 2 + + reset-names: + items: + - const: ufshc-rst + - const: ufsphy-rst + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + #include + ufs@f10b0000 { + compatible = "amd,versal2-ufs"; + reg = <0xf10b0000 0x1000>; + interrupts = ; + clocks = <&ufs_core_clk>, <&ufs_phy_clk>, <&ufs_ref_clk>; + clock-names = "core_clk", "phy_clk", "ref_clk"; + freq-table-hz = <0 0>, <0 0>, <0 0>; + resets = <&scmi_reset 4>, <&scmi_reset 35>; + reset-names = "ufshc-rst", "ufsphy-rst"; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/usb/microchip,usb2244.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/usb/microchip,usb2244.yaml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/microchip,usb2244.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip USB2244 Ultra Fast USB-SD Controller + +description: + Microchip’s USB224x is a USB 2.0 compliant, Hi-Speed bulk only mass + storage class peripheral controller intended for reading and writing + to popular flash media from the xDPicture Card™, Memory Stick® (MS), + Secure Digital (SD), and MultiMediaCard™ (MMC) families. + + USB224x is a flash media card reader solution fully compliant with the + USB 2.0 specification + +maintainers: + - Piyush Mehta + +properties: + compatible: + const: microchip,usb2244 + + reset-gpios: + maxItems: 1 + description: + The phandle and specifier for the GPIO that controls the RESET line of + flash media controller. + +required: + - compatible + +additionalProperties: false + +examples: + - | + #include + + usb { + compatible = "microchip,usb2244"; + reset-gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -366,6 +366,13 @@ minimum: 1 maximum: 16 + snps,xhci-reset-on-resume: + description: + When set, xhci host will reset the host controller on resume from + suspend. Some controllers might lose power during suspend, so host + require re-initialization. + type: boolean + snps,rx-thr-num-pkt-prd: description: Periodic ESS RX packet threshold count (host mode only). Set this and --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/usb/ulpi-phy.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/usb/ulpi-phy.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/ulpi-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ULPI PHY- Generic platform + +maintainers: + - Piyush Mehta + +properties: + compatible: + const: ulpi-phy + + reg: + maxItems: 1 + + '#phy-cells': + const: 0 + + external-drv-vbus: + description: + If present, configure ulpi-phy external supply to drive 5V on VBus. + type: boolean + + view-port: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Address to read and write PHY registers with explicit control of + the address and data using the usb.VIEWPORT register. + +required: + - compatible + - reg + - view-port + +additionalProperties: false + +examples: + - | + phy0@e0002000 { + compatible = "ulpi-phy"; + #phy-cells = <0x00>; + reg = <0xe0002000 0x1000>; + view-port = <0x170>; + external-drv-vbus; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/usb/usb-xhci.yaml +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/usb/usb-xhci.yaml @@ -21,6 +21,13 @@ description: Determines if platform is USB3 LPM capable type: boolean + snps,xhci-reset-on-resume: + description: + When set, xhci host will reset the host controller on resume from + suspend. Some controllers might lose power during suspend, so host + require re-initialization. + type: boolean + quirk-broken-port-ped: description: Set if the controller has broken port disable mechanism type: boolean --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/xlnx,ctrl-fb.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/xlnx,ctrl-fb.txt @@ -0,0 +1,22 @@ +The Xilinx framebuffer DMA engine supports two soft IP blocks: one IP +block is used for reading video frame data from memory (FB Read) to the device +and the other IP block is used for writing video frame data from the device +to memory (FB Write). Both the FB Read/Write IP blocks are aware of the +format of the data being written to or read from memory including RGB and +YUV in packed, planar, and semi-planar formats. Because the FB Read/Write +is format aware, only one buffer pointer is needed by the IP blocks even +when planar or semi-planar format are used. + +Required properties: + - compatible: Should be "xlnx,ctrl-fbwr-1.0" for framebuffer Write OR + "xlnx,ctrl-fbrd-1.0" for framebuffer Read. + - reg: Base address and size of the IP core. + - reset-gpios: gpio to reset the framebuffer IP + +Example: + + fbwr@0xa0000000 { + compatible = "xlnx,ctrl-fbwr-1.0"; + reg = <0x0 0xa0000000 0x0 0x10000>; + reset-gpios = <&gpio 82 1>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/bindings/xlnx,ctrl-vpss.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/bindings/xlnx,ctrl-vpss.txt @@ -0,0 +1,21 @@ +The Xilinx VPSS Scaler is a Video IP that supports up scaling, down scaling and +no scaling functionailty along with color space conversion. This supports custom +resolution values between 0 to 4096. + +Required properties: + +- compatible: Must be "xlnx,ctrl-xvpss-1.0". +- reg: Base address and size of the IP core. +- reset-gpios: gpio to reset the framebuffer IP +- xlnx,vpss-taps: number of taps +- xlnx,vpss-ppc: pixels per clock + +Example: + + ctrlvpss: vpss@0xa0200000 { + compatible = "xlnx,ctrl-xvpss-1.0"; + reg = <0x0 0xa0200000 0x0 0x30000>; + reset-gpios = <&gpio 80 1>; + xlnx,vpss-taps = <6>; + xlnx,vpss-ppc = <2>; + }; --- linux-xilinx-6.8.0.orig/Documentation/devicetree/configfs-overlays.txt +++ linux-xilinx-6.8.0/Documentation/devicetree/configfs-overlays.txt @@ -0,0 +1,31 @@ +Howto use the configfs overlay interface. + +A device-tree configfs entry is created in /config/device-tree/overlays +and and it is manipulated using standard file system I/O. +Note that this is a debug level interface, for use by developers and +not necessarily something accessed by normal users due to the +security implications of having direct access to the kernel's device tree. + +* To create an overlay you mkdir the directory: + + # mkdir /config/device-tree/overlays/foo + +* Either you echo the overlay firmware file to the path property file. + + # echo foo.dtbo >/config/device-tree/overlays/foo/path + +* Or you cat the contents of the overlay to the dtbo file + + # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo + +The overlay file will be applied, and devices will be created/destroyed +as required. + +To remove it simply rmdir the directory. + + # rmdir /config/device-tree/overlays/foo + +The rationalle of the dual interface (firmware & direct copy) is that each is +better suited to different use patterns. The firmware interface is what's +intended to be used by hardware managers in the kernel, while the copy interface +make sense for developers (since it avoids problems with namespaces). --- linux-xilinx-6.8.0.orig/Documentation/driver-api/fpga/fpga-bridge.rst +++ linux-xilinx-6.8.0/Documentation/driver-api/fpga/fpga-bridge.rst @@ -6,9 +6,12 @@ * struct fpga_bridge - The FPGA Bridge structure * struct fpga_bridge_ops - Low level Bridge driver ops -* fpga_bridge_register() - Create and register a bridge +* __fpga_bridge_register() - Create and register a bridge * fpga_bridge_unregister() - Unregister a bridge +The helper macro ``fpga_bridge_register()`` automatically sets +the module that registers the FPGA bridge as the owner. + .. kernel-doc:: include/linux/fpga/fpga-bridge.h :functions: fpga_bridge @@ -16,7 +19,7 @@ :functions: fpga_bridge_ops .. kernel-doc:: drivers/fpga/fpga-bridge.c - :functions: fpga_bridge_register + :functions: __fpga_bridge_register .. kernel-doc:: drivers/fpga/fpga-bridge.c :functions: fpga_bridge_unregister --- linux-xilinx-6.8.0.orig/Documentation/driver-api/fpga/fpga-mgr.rst +++ linux-xilinx-6.8.0/Documentation/driver-api/fpga/fpga-mgr.rst @@ -24,7 +24,8 @@ -------------------------------- To add another FPGA manager, write a driver that implements a set of ops. The -probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as:: +probe function calls ``fpga_mgr_register()`` or ``fpga_mgr_register_full()``, +such as:: static const struct fpga_manager_ops socfpga_fpga_ops = { .write_init = socfpga_fpga_ops_configure_init, @@ -69,10 +70,11 @@ } Alternatively, the probe function could call one of the resource managed -register functions, devm_fpga_mgr_register() or devm_fpga_mgr_register_full(). -When these functions are used, the parameter syntax is the same, but the call -to fpga_mgr_unregister() should be removed. In the above example, the -socfpga_fpga_remove() function would not be required. +register functions, ``devm_fpga_mgr_register()`` or +``devm_fpga_mgr_register_full()``. When these functions are used, the +parameter syntax is the same, but the call to ``fpga_mgr_unregister()`` should be +removed. In the above example, the ``socfpga_fpga_remove()`` function would not be +required. The ops will implement whatever device specific register writes are needed to do the programming sequence for this particular FPGA. These ops return 0 for @@ -125,15 +127,19 @@ * struct fpga_manager - the FPGA manager struct * struct fpga_manager_ops - Low level FPGA manager driver ops * struct fpga_manager_info - Parameter structure for fpga_mgr_register_full() -* fpga_mgr_register_full() - Create and register an FPGA manager using the +* __fpga_mgr_register_full() - Create and register an FPGA manager using the fpga_mgr_info structure to provide the full flexibility of options -* fpga_mgr_register() - Create and register an FPGA manager using standard +* __fpga_mgr_register() - Create and register an FPGA manager using standard arguments -* devm_fpga_mgr_register_full() - Resource managed version of - fpga_mgr_register_full() -* devm_fpga_mgr_register() - Resource managed version of fpga_mgr_register() +* __devm_fpga_mgr_register_full() - Resource managed version of + __fpga_mgr_register_full() +* __devm_fpga_mgr_register() - Resource managed version of __fpga_mgr_register() * fpga_mgr_unregister() - Unregister an FPGA manager +Helper macros ``fpga_mgr_register_full()``, ``fpga_mgr_register()``, +``devm_fpga_mgr_register_full()``, and ``devm_fpga_mgr_register()`` are available +to ease the registration. + .. kernel-doc:: include/linux/fpga/fpga-mgr.h :functions: fpga_mgr_states @@ -147,16 +153,16 @@ :functions: fpga_manager_info .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: fpga_mgr_register_full + :functions: __fpga_mgr_register_full .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: fpga_mgr_register + :functions: __fpga_mgr_register .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: devm_fpga_mgr_register_full + :functions: __devm_fpga_mgr_register_full .. kernel-doc:: drivers/fpga/fpga-mgr.c - :functions: devm_fpga_mgr_register + :functions: __devm_fpga_mgr_register .. kernel-doc:: drivers/fpga/fpga-mgr.c :functions: fpga_mgr_unregister --- linux-xilinx-6.8.0.orig/Documentation/driver-api/fpga/fpga-region.rst +++ linux-xilinx-6.8.0/Documentation/driver-api/fpga/fpga-region.rst @@ -46,13 +46,16 @@ ---------------------------- * struct fpga_region - The FPGA region struct -* struct fpga_region_info - Parameter structure for fpga_region_register_full() -* fpga_region_register_full() - Create and register an FPGA region using the +* struct fpga_region_info - Parameter structure for __fpga_region_register_full() +* __fpga_region_register_full() - Create and register an FPGA region using the fpga_region_info structure to provide the full flexibility of options -* fpga_region_register() - Create and register an FPGA region using standard +* __fpga_region_register() - Create and register an FPGA region using standard arguments * fpga_region_unregister() - Unregister an FPGA region +Helper macros ``fpga_region_register()`` and ``fpga_region_register_full()`` +automatically set the module that registers the FPGA region as the owner. + The FPGA region's probe function will need to get a reference to the FPGA Manager it will be using to do the programming. This usually would happen during the region's probe function. @@ -82,10 +85,10 @@ :functions: fpga_region_info .. kernel-doc:: drivers/fpga/fpga-region.c - :functions: fpga_region_register_full + :functions: __fpga_region_register_full .. kernel-doc:: drivers/fpga/fpga-region.c - :functions: fpga_region_register + :functions: __fpga_region_register .. kernel-doc:: drivers/fpga/fpga-region.c :functions: fpga_region_unregister --- linux-xilinx-6.8.0.orig/Documentation/driver-api/soundwire/stream.rst +++ linux-xilinx-6.8.0/Documentation/driver-api/soundwire/stream.rst @@ -324,12 +324,12 @@ int sdw_stream_add_master(struct sdw_bus * bus, struct sdw_stream_config * stream_config, - struct sdw_ports_config * ports_config, + const struct sdw_ports_config * ports_config, struct sdw_stream_runtime * stream); int sdw_stream_add_slave(struct sdw_slave * slave, struct sdw_stream_config * stream_config, - struct sdw_ports_config * ports_config, + const struct sdw_ports_config * ports_config, struct sdw_stream_runtime * stream); --- linux-xilinx-6.8.0.orig/Documentation/filesystems/f2fs.rst +++ linux-xilinx-6.8.0/Documentation/filesystems/f2fs.rst @@ -126,9 +126,7 @@ discard/nodiscard Enable/disable real-time discard in f2fs, if discard is enabled, f2fs will issue discard/TRIM commands when a segment is cleaned. -no_heap Disable heap-style segment allocation which finds free - segments for data from the beginning of main area, while - for node from the end of main area. +heap/no_heap Deprecated. nouser_xattr Disable Extended User Attributes. Note: xattr is enabled by default if CONFIG_F2FS_FS_XATTR is selected. noacl Disable POSIX Access Control List. Note: acl is enabled @@ -228,8 +226,6 @@ option for more randomness. Please, use these options for your experiments and we strongly recommend to re-format the filesystem after using these options. -io_bits=%u Set the bit size of write IO requests. It should be set - with "mode=lfs". usrquota Enable plain user disk quota accounting. grpquota Enable plain group disk quota accounting. prjquota Enable plain project quota accounting. --- linux-xilinx-6.8.0.orig/Documentation/kbuild/modules.rst +++ linux-xilinx-6.8.0/Documentation/kbuild/modules.rst @@ -128,7 +128,7 @@ modules_install Install the external module(s). The default location is - /lib/modules//extra/, but a prefix may + /lib/modules//updates/, but a prefix may be added with INSTALL_MOD_PATH (discussed in section 5). clean @@ -417,7 +417,7 @@ And external modules are installed in: - /lib/modules/$(KERNELRELEASE)/extra/ + /lib/modules/$(KERNELRELEASE)/updates/ 5.1 INSTALL_MOD_PATH -------------------- @@ -438,10 +438,10 @@ ------------------- External modules are by default installed to a directory under - /lib/modules/$(KERNELRELEASE)/extra/, but you may wish to + /lib/modules/$(KERNELRELEASE)/updates/, but you may wish to locate modules for a specific functionality in a separate directory. For this purpose, use INSTALL_MOD_DIR to specify an - alternative name to "extra.":: + alternative name to "updates.":: $ make INSTALL_MOD_DIR=gandalf -C $KDIR \ M=$PWD modules_install --- linux-xilinx-6.8.0.orig/Documentation/misc-devices/xilinx_sdfec.rst +++ linux-xilinx-6.8.0/Documentation/misc-devices/xilinx_sdfec.rst @@ -29,7 +29,7 @@ - Does not support shared LDPC code table wraparound The device tree entry is described in: -`linux-xlnx/Documentation/devicetree/bindings/misc/xlnx,sd-fec.txt `_ +`linux-xlnx/Documentation/devicetree/bindings/misc/xlnx,sd-fec.yaml `_ Modes of Operation --- linux-xilinx-6.8.0.orig/Documentation/mm/arch_pgtable_helpers.rst +++ linux-xilinx-6.8.0/Documentation/mm/arch_pgtable_helpers.rst @@ -140,7 +140,8 @@ +---------------------------+--------------------------------------------------+ | pmd_swp_clear_soft_dirty | Clears a soft dirty swapped PMD | +---------------------------+--------------------------------------------------+ -| pmd_mkinvalid | Invalidates a mapped PMD [1] | +| pmd_mkinvalid | Invalidates a present PMD; do not call for | +| | non-present PMD [1] | +---------------------------+--------------------------------------------------+ | pmd_set_huge | Creates a PMD huge mapping | +---------------------------+--------------------------------------------------+ @@ -196,7 +197,8 @@ +---------------------------+--------------------------------------------------+ | pud_mkdevmap | Creates a ZONE_DEVICE mapped PUD | +---------------------------+--------------------------------------------------+ -| pud_mkinvalid | Invalidates a mapped PUD [1] | +| pud_mkinvalid | Invalidates a present PUD; do not call for | +| | non-present PUD [1] | +---------------------------+--------------------------------------------------+ | pud_set_huge | Creates a PUD huge mapping | +---------------------------+--------------------------------------------------+ --- linux-xilinx-6.8.0.orig/Documentation/netlink/specs/devlink.yaml +++ linux-xilinx-6.8.0/Documentation/netlink/specs/devlink.yaml @@ -290,7 +290,7 @@ enum: eswitch-mode - name: eswitch-inline-mode - type: u16 + type: u8 enum: eswitch-inline-mode - name: dpipe-tables --- linux-xilinx-6.8.0.orig/Documentation/netlink/specs/dpll.yaml +++ linux-xilinx-6.8.0/Documentation/netlink/specs/dpll.yaml @@ -274,6 +274,7 @@ - name: capabilities type: u32 + enum: pin-capabilities - name: parent-device type: nest --- linux-xilinx-6.8.0.orig/Documentation/netlink/specs/rt_link.yaml +++ linux-xilinx-6.8.0/Documentation/netlink/specs/rt_link.yaml @@ -1144,6 +1144,12 @@ - name: mcast-querier-state type: binary + - + name: fdb-n-learned + type: u32 + - + name: fdb-max-learned + type: u32 - name: linkinfo-brport-attrs name-prefix: ifla-brport- --- linux-xilinx-6.8.0.orig/Documentation/networking/device_drivers/wwan/t7xx.rst +++ linux-xilinx-6.8.0/Documentation/networking/device_drivers/wwan/t7xx.rst @@ -39,6 +39,34 @@ - open the AT control channel using a UART tool or a special user tool +Sysfs +===== +The driver provides sysfs interfaces to userspace. + +t7xx_mode +--------- +The sysfs interface provides userspace with access to the device mode, this interface +supports read and write operations. + +Device mode: + +- ``unknown`` represents that device in unknown status +- ``ready`` represents that device in ready status +- ``reset`` represents that device in reset status +- ``fastboot_switching`` represents that device in fastboot switching status +- ``fastboot_download`` represents that device in fastboot download status +- ``fastboot_dump`` represents that device in fastboot dump status + +Read from userspace to get the current device mode. + +:: + $ cat /sys/bus/pci/devices/${bdf}/t7xx_mode + +Write from userspace to set the device mode. + +:: + $ echo fastboot_switching > /sys/bus/pci/devices/${bdf}/t7xx_mode + Management application development ================================== The driver and userspace interfaces are described below. The MBIM protocol is @@ -97,6 +125,20 @@ The userspace end of the control port is a /dev/wwan0at0 character device. Application shall use this interface to issue AT commands. +fastboot port userspace ABI +--------------------------- + +/dev/wwan0fastboot0 character device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The driver exposes a fastboot protocol interface by implementing +fastboot WWAN Port. The userspace end of the fastboot channel pipe is a +/dev/wwan0fastboot0 character device. Application shall use this interface for +fastboot protocol communication. + +Please note that driver needs to be reloaded to export /dev/wwan0fastboot0 +port, because device needs a cold reset after enter ``fastboot_switching`` +mode. + The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification. References @@ -118,3 +160,7 @@ [4] *Specification # 27.007 - 3GPP* - https://www.3gpp.org/DynaReport/27007.htm + +[5] *fastboot "a mechanism for communicating with bootloaders"* + +- https://android.googlesource.com/platform/system/core/+/refs/heads/main/fastboot/README.md --- linux-xilinx-6.8.0.orig/Documentation/networking/net_cachelines/net_device.rst +++ linux-xilinx-6.8.0/Documentation/networking/net_cachelines/net_device.rst @@ -13,7 +13,7 @@ unsigned_long mem_end unsigned_long mem_start unsigned_long base_addr -unsigned_long state +unsigned_long state read_mostly read_mostly netif_running(dev) struct_list_head dev_list struct_list_head napi_list struct_list_head unreg_list --- linux-xilinx-6.8.0.orig/Documentation/networking/sfp-phylink.rst +++ linux-xilinx-6.8.0/Documentation/networking/sfp-phylink.rst @@ -207,6 +207,11 @@ capabilities for ``interface`` to determine the allowable ethtool link modes. + The :c:func:`validate` method should mask the supplied supported mask, + and ``state->advertising`` with the supported ethtool link modes. + These are the new ethtool link modes, so bitmask operations must be + used. For an example, see ``drivers/net/ethernet/marvell/mvneta.c``. + The :c:func:`mac_link_state` method is used to read the link state from the MAC, and report back the settings that the MAC is currently using. This is particularly important for in-band negotiation --- linux-xilinx-6.8.0.orig/Documentation/process/changes.rst +++ linux-xilinx-6.8.0/Documentation/process/changes.rst @@ -31,7 +31,7 @@ ====================== =============== ======================================== GNU C 5.1 gcc --version Clang/LLVM (optional) 11.0.0 clang --version -Rust (optional) 1.74.1 rustc --version +Rust (optional) 1.75.0 rustc --version bindgen (optional) 0.65.1 bindgen --version GNU make 3.82 make --version bash 4.2 bash --version --- linux-xilinx-6.8.0.orig/Documentation/sphinx/cdomain.py +++ linux-xilinx-6.8.0/Documentation/sphinx/cdomain.py @@ -37,12 +37,29 @@ import sphinx from sphinx import addnodes -from sphinx.domains.c import c_funcptr_sig_re, c_sig_re from sphinx.domains.c import CObject as Base_CObject from sphinx.domains.c import CDomain as Base_CDomain from itertools import chain import re +# fixes https://github.com/sphinx-doc/sphinx/commit/0f49e30c51b5cc5055cda5b4b294c2dd9d1df573#r38750737 + +# pylint: disable=invalid-name +c_sig_re = re.compile( + r'''^([^(]*?) # return type + ([\w:.]+) \s* # thing name (colon allowed for C++) + (?: \((.*)\) )? # optionally arguments + (\s+const)? $ # const specifier + ''', re.VERBOSE) + +c_funcptr_sig_re = re.compile( + r'''^([^(]+?) # return type + (\( [^()]+ \)) \s* # name in parentheses + \( (.*) \) # arguments + (\s+const)? $ # const specifier + ''', re.VERBOSE) +# pylint: enable=invalid-name + __version__ = '1.1' # Get Sphinx version --- linux-xilinx-6.8.0.orig/Documentation/sphinx/kernel_include.py +++ linux-xilinx-6.8.0/Documentation/sphinx/kernel_include.py @@ -97,7 +97,6 @@ # HINT: this is the only line I had to change / commented out: #path = utils.relative_path(None, path) - path = nodes.reprunicode(path) encoding = self.options.get( 'encoding', self.state.document.settings.input_encoding) e_handler=self.state.document.settings.input_encoding_error_handler --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/mediactl/media-types.rst +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/mediactl/media-types.rst @@ -375,12 +375,11 @@ are origins of links. * - ``MEDIA_PAD_FL_MUST_CONNECT`` - - If this flag is set and the pad is linked to any other pad, then - at least one of those links must be enabled for the entity to be - able to stream. There could be temporary reasons (e.g. device - configuration dependent) for the pad to need enabled links even - when this flag isn't set; the absence of the flag doesn't imply - there is none. + - If this flag is set, then for this pad to be able to stream, it must + be connected by at least one enabled link. There could be temporary + reasons (e.g. device configuration dependent) for the pad to need + enabled links even when this flag isn't set; the absence of the flag + doesn't imply there is none. One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE`` --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/v4l/biblio.rst +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/v4l/biblio.rst @@ -436,3 +436,13 @@ :title: AV1 Bitstream & Decoding Process Specification :author: Peter de Rivaz, Argon Design Ltd, Jack Haughton, Argon Design Ltd + +.. _itu2100: + +ITU BT.2100 +=========== + + +:title: ITU-R Recommendation BT.2100-2 (07/2018) "Image parameter values for high dynamic range television for use in production and international programme exchange" + +:author: International Telecommunication Union (http://www.itu.int) --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/v4l/colorspaces-defs.rst +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/v4l/colorspaces-defs.rst @@ -99,6 +99,8 @@ - Use the DCI-P3 transfer function. * - ``V4L2_XFER_FUNC_SMPTE2084`` - Use the SMPTE 2084 transfer function. See :ref:`xf-smpte-2084`. + * - ``V4L2_XFER_FUNC_HLG`` + - Use the Hybrid Log Gamma(HLG) transfer function. See :ref:`xf-hlg`. --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/v4l/colorspaces-details.rst +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/v4l/colorspaces-details.rst @@ -773,3 +773,34 @@ There are better methods, see e.g. :ref:`colimg` for more in-depth information about this. + + +.. _xf-hlg: + +Transfer Function HLG (V4L2_XFER_FUNC_HLG) +======================================================= + +The :ref:`itu2100` defines the transfer function used. + +Constants: + +.. math:: + a = 0.17883277 + + b = 1 - 4 * a = 0.28466892 + + c = 0.5 - a * \ln (4 * a) = 0.55991073 + +Transfer function: + +.. math:: + + E' = \begin{cases}\sqrt(3 * E) & 0 \leq E \leq \frac{1}{12} + \\ a * \ln(12 * E - b) + c & \frac{1}{12} \le E \leq 1\end{cases} + +Inverse Transfer function: + +.. math:: + + x' =\begin{cases}x^{2} / 3 & 0 \leq x \leq \frac{1}{12} + \\(exp((x - c) / a) + b) / 12 & \frac{1}{12} \le x \leq 1\end{cases} --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/v4l/subdev-formats.rst +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/v4l/subdev-formats.rst @@ -1860,6 +1860,43 @@ - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + * .. _MEDIA-BUS-FMT-RBG101010-1X30: + + - MEDIA_BUS_FMT_RBG101010_1X30 + - 0x1100 + - + - 0 + - 0 + - r\ :sub:`9` + - r\ :sub:`8` + - r\ :sub:`7` + - r\ :sub:`6` + - r\ :sub:`5` + - r\ :sub:`4` + - r\ :sub:`3` + - r\ :sub:`2` + - r\ :sub:`1` + - r\ :sub:`0` + - b\ :sub:`9` + - b\ :sub:`8` + - b\ :sub:`7` + - b\ :sub:`6` + - b\ :sub:`5` + - b\ :sub:`4` + - b\ :sub:`3` + - b\ :sub:`2` + - b\ :sub:`1` + - b\ :sub:`0` + - g\ :sub:`9` + - g\ :sub:`8` + - g\ :sub:`7` + - g\ :sub:`6` + - g\ :sub:`5` + - g\ :sub:`4` + - g\ :sub:`3` + - g\ :sub:`2` + - g\ :sub:`1` + - g\ :sub:`0` .. raw:: latex @@ -2049,6 +2086,47 @@ - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + * .. _MEDIA-BUS-FMT-RBG121212-1X36: + + - MEDIA_BUS_FMT_RBG121212_1X36 + - 0x1101 + - + - r\ :sub:`11` + - r\ :sub:`10` + - r\ :sub:`9` + - r\ :sub:`8` + - r\ :sub:`7` + - r\ :sub:`6` + - r\ :sub:`5` + - r\ :sub:`4` + - r\ :sub:`3` + - r\ :sub:`2` + - r\ :sub:`1` + - r\ :sub:`0` + - b\ :sub:`11` + - b\ :sub:`10` + - b\ :sub:`9` + - b\ :sub:`8` + - b\ :sub:`7` + - b\ :sub:`6` + - b\ :sub:`5` + - b\ :sub:`4` + - b\ :sub:`3` + - b\ :sub:`2` + - b\ :sub:`1` + - b\ :sub:`0` + - g\ :sub:`11` + - g\ :sub:`10` + - g\ :sub:`9` + - g\ :sub:`8` + - g\ :sub:`7` + - g\ :sub:`6` + - g\ :sub:`5` + - g\ :sub:`4` + - g\ :sub:`3` + - g\ :sub:`2` + - g\ :sub:`1` + - g\ :sub:`0` .. raw:: latex @@ -2218,6 +2296,78 @@ - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + * .. _MEDIA-BUS-FMT-RBG161616-1X48: + + - MEDIA_BUS_FMT_RBG161616_1X48 + - 0x1102 + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - r\ :sub:`15` + - r\ :sub:`14` + - r\ :sub:`13` + - r\ :sub:`12` + - r\ :sub:`11` + - r\ :sub:`10` + - r\ :sub:`9` + - r\ :sub:`8` + - r\ :sub:`7` + - r\ :sub:`6` + - r\ :sub:`5` + - r\ :sub:`4` + - r\ :sub:`3` + - r\ :sub:`2` + - r\ :sub:`1` + - r\ :sub:`0` + * - + - + - + - b\ :sub:`15` + - b\ :sub:`14` + - b\ :sub:`13` + - b\ :sub:`12` + - b\ :sub:`11` + - b\ :sub:`10` + - b\ :sub:`9` + - b\ :sub:`8` + - b\ :sub:`7` + - b\ :sub:`6` + - b\ :sub:`5` + - b\ :sub:`4` + - b\ :sub:`3` + - b\ :sub:`2` + - b\ :sub:`1` + - b\ :sub:`0` + - g\ :sub:`15` + - g\ :sub:`14` + - g\ :sub:`13` + - g\ :sub:`12` + - g\ :sub:`11` + - g\ :sub:`10` + - g\ :sub:`9` + - g\ :sub:`8` + - g\ :sub:`7` + - g\ :sub:`6` + - g\ :sub:`5` + - g\ :sub:`4` + - g\ :sub:`3` + - g\ :sub:`2` + - g\ :sub:`1` + - g\ :sub:`0` .. raw:: latex @@ -5598,6 +5748,148 @@ - u\ :sub:`2` - u\ :sub:`1` - u\ :sub:`0` + * .. _MEDIA-BUS-FMT-VYYUYY10_4X20: + + - MEDIA_BUS_FMT_VYYUYY10_4X20 + - 0x2101 + - + - + - + - + - + - + - + - + - + - + - + - + - + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` * .. _MEDIA-BUS-FMT-Y12-1X12: - MEDIA_BUS_FMT_Y12_1X12 @@ -7429,6 +7721,185 @@ - u\ :sub:`2` - u\ :sub:`1` - u\ :sub:`0` + * .. _MEDIA-BUS-FMT-UYYVYY12-4X24: + + - MEDIA_BUS_FMT_UYYVYY12_4X24 + - 0x2103 + - + - + - + - + - + - + - + - + - + - u\ :sub:`11` + - u\ :sub:`10` + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - v\ :sub:`11` + - v\ :sub:`10` + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * .. _MEDIA-BUS-FMT-VYYUYY8-1X24: + + - MEDIA_BUS_FMT_VYYUYY8_1X24 + - 0x2100 + - + - + - + - + - + - + - + - + - + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` * .. _MEDIA-BUS-FMT-YUV10-1X30: - MEDIA_BUS_FMT_YUV10_1X30 @@ -7466,6 +7937,43 @@ - v\ :sub:`2` - v\ :sub:`1` - v\ :sub:`0` + * .. _MEDIA-BUS-FMT-VUY10-1X30: + + - MEDIA_BUS_FMT_VUY10_1X30 + - 0x2102 + - + - + - + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` * .. _MEDIA-BUS-FMT-UYYVYY10-0-5X30: - MEDIA_BUS_FMT_UYYVYY10_0_5X30 @@ -7575,6 +8083,220 @@ - v\ :sub:`2` - v\ :sub:`1` - v\ :sub:`0` + * .. _MEDIA-BUS-FMT-UYYVYY16-4X32: + + - MEDIA_BUS_FMT_UYYVYY16_4X32 + - 0x2106 + - + - u\ :sub:`15` + - u\ :sub:`14` + - u\ :sub:`13` + - u\ :sub:`12` + - u\ :sub:`11` + - u\ :sub:`10` + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - v\ :sub:`15` + - v\ :sub:`14` + - v\ :sub:`13` + - v\ :sub:`12` + - v\ :sub:`11` + - v\ :sub:`10` + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * .. _MEDIA-BUS-FMT-UYVY16-2X32: + + - MEDIA_BUS_FMT_UYVY16_2X32 + - 0x2108 + - + - u\ :sub:`15` + - u\ :sub:`14` + - u\ :sub:`13` + - u\ :sub:`12` + - u\ :sub:`11` + - u\ :sub:`10` + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` + * - + - + - + - v\ :sub:`15` + - v\ :sub:`14` + - v\ :sub:`13` + - v\ :sub:`12` + - v\ :sub:`11` + - v\ :sub:`10` + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` .. raw:: latex @@ -7763,6 +8485,47 @@ - v\ :sub:`2` - v\ :sub:`1` - v\ :sub:`0` + * .. _MEDIA-BUS-FMT-VUY12-1X36: + + - MEDIA_BUS_FMT_VUY12_1X36 + - 0x2104 + - + - v\ :sub:`11` + - v\ :sub:`10` + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + - u\ :sub:`11` + - u\ :sub:`10` + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`9` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` .. raw:: latex @@ -7933,6 +8696,78 @@ - v\ :sub:`2` - v\ :sub:`1` - v\ :sub:`0` + * .. _MEDIA-BUS-FMT-VUY16-1X48: + + - MEDIA_BUS_FMT_VUY16_1X48 + - 0x2107 + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - v\ :sub:`15` + - v\ :sub:`14` + - v\ :sub:`13` + - v\ :sub:`12` + - v\ :sub:`11` + - v\ :sub:`10` + - v\ :sub:`9` + - v\ :sub:`8` + - v\ :sub:`7` + - v\ :sub:`6` + - v\ :sub:`5` + - v\ :sub:`4` + - v\ :sub:`3` + - v\ :sub:`2` + - v\ :sub:`1` + - v\ :sub:`0` + * - + - + - + - u\ :sub:`15` + - u\ :sub:`14` + - u\ :sub:`13` + - u\ :sub:`12` + - u\ :sub:`11` + - u\ :sub:`10` + - u\ :sub:`9` + - u\ :sub:`8` + - u\ :sub:`7` + - u\ :sub:`6` + - u\ :sub:`5` + - u\ :sub:`4` + - u\ :sub:`3` + - u\ :sub:`2` + - u\ :sub:`1` + - u\ :sub:`0` + - y\ :sub:`15` + - y\ :sub:`14` + - y\ :sub:`13` + - y\ :sub:`12` + - y\ :sub:`11` + - y\ :sub:`10` + - y\ :sub:`8` + - y\ :sub:`8` + - y\ :sub:`7` + - y\ :sub:`6` + - y\ :sub:`5` + - y\ :sub:`4` + - y\ :sub:`3` + - y\ :sub:`2` + - y\ :sub:`1` + - y\ :sub:`0` * .. _MEDIA-BUS-FMT-UYYVYY16-0-5X48: - MEDIA_BUS_FMT_UYYVYY16_0_5X48 --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst @@ -471,6 +471,12 @@ - n/a - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264 decode parameters for stateless video decoders. + * - ``V4L2_CTRL_TYPE_HDR`` + - n/a + - n/a + - n/a + - A struct :c:type:`v4l2_metadata_hdr`, containing HDR + metadata. * - ``V4L2_CTRL_TYPE_FWHT_PARAMS`` - n/a - n/a --- linux-xilinx-6.8.0.orig/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ linux-xilinx-6.8.0/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -82,6 +82,7 @@ replace symbol V4L2_XFER_FUNC_SMPTE2084 :c:type:`v4l2_xfer_func` replace symbol V4L2_XFER_FUNC_SMPTE240M :c:type:`v4l2_xfer_func` replace symbol V4L2_XFER_FUNC_SRGB :c:type:`v4l2_xfer_func` +replace symbol V4L2_XFER_FUNC_HLG :c:type:`v4l2_xfer_func` replace symbol V4L2_XFER_FUNC_LAST :c:type:`v4l2_xfer_func` # Documented enum v4l2_ycbcr_encoding --- linux-xilinx-6.8.0.orig/Documentation/virt/kvm/api.rst +++ linux-xilinx-6.8.0/Documentation/virt/kvm/api.rst @@ -2439,8 +2439,11 @@ PPC KVM_REG_PPC_PSSCR 64 PPC KVM_REG_PPC_DEC_EXPIRY 64 PPC KVM_REG_PPC_PTCR 64 + PPC KVM_REG_PPC_HASHKEYR 64 + PPC KVM_REG_PPC_HASHPKEYR 64 PPC KVM_REG_PPC_DAWR1 64 PPC KVM_REG_PPC_DAWRX1 64 + PPC KVM_REG_PPC_DEXCR 64 PPC KVM_REG_PPC_TM_GPR0 64 ... PPC KVM_REG_PPC_TM_GPR31 64 --- linux-xilinx-6.8.0.orig/Kbuild +++ linux-xilinx-6.8.0/Kbuild @@ -97,3 +97,4 @@ obj-$(CONFIG_NET) += net/ obj-y += virt/ obj-y += $(ARCH_DRIVERS) +obj-y += ubuntu/ --- linux-xilinx-6.8.0.orig/Kconfig +++ linux-xilinx-6.8.0/Kconfig @@ -19,6 +19,8 @@ source "drivers/Kconfig" +source "ubuntu/Kconfig" + source "fs/Kconfig" source "security/Kconfig" --- linux-xilinx-6.8.0.orig/MAINTAINERS +++ linux-xilinx-6.8.0/MAINTAINERS @@ -190,6 +190,18 @@ F: Documentation/devicetree/bindings/power/supply/*ab8500* F: drivers/power/supply/*ab8500* +AAEON DEVICE DRIVER WITH WMI INTERFACE +M: Edward Lin +M: Kunyang Fan +M: Frank Hsieh +M: Jacob Wu +S: Supported +F: drivers/gpio/gpio-aaeon.c +F: drivers/hwmon/hwmon-aaeon.c +F: drivers/leds/leds-aaeon.c +F: drivers/mfd/mfd-aaeon.c +F: drivers/watchdog/wdt_aaeon.c + ABI/API L: linux-api@vger.kernel.org F: include/linux/syscalls.h @@ -1054,7 +1066,6 @@ S: Supported F: Documentation/admin-guide/pm/amd-pstate.rst F: drivers/cpufreq/amd-pstate* -F: include/linux/amd-pstate.h F: tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py AMD PTDMA DRIVER @@ -4896,6 +4907,15 @@ F: Documentation/hwmon/powerz.rst F: drivers/hwmon/powerz.c +CHAR and MISC XILINX AI ENGINE DRIVER +M: Gregory Williams +M: Govindarajulu Varadarajan +S: Maintained +F: Documentation/devicetree/bindings/soc/xilinx/xlnx,ai-engine.yaml +F: drivers/misc/xilinx-ai-engine/ +F: include/linux/xlnx-ai-engine.h +F: include/uapi/linux/xlnx-ai-engine.h + CHECKPATCH M: Andy Whitcroft M: Joe Perches @@ -10389,6 +10409,14 @@ S: Maintained F: drivers/media/rc/iguanair.c +IIO BACKEND FRAMEWORK +M: Nuno Sa +R: Olivier Moysan +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/iio/industrialio-backend.c +F: include/linux/iio/backend.h + IIO DIGITAL POTENTIOMETER DAC M: Peter Rosin L: linux-iio@vger.kernel.org @@ -10510,6 +10538,14 @@ F: drivers/hwmon/ina2xx.c F: include/linux/platform_data/ina2xx.h +INA260 POWER MONITOR DRIVER +M: Shubhrajyoti Datta +R: Raviteja Narayanam +R: Michal Simek +S: Maintained +F: drivers/iio/adc/ina260-adc.c +F: Documentation/devicetree/bindings/iio/adc/ti,ina260.yaml + INDEX OF FURTHER KERNEL DOCUMENTATION M: Carlos Bilbao S: Maintained @@ -16320,8 +16356,8 @@ M: Matthias Kaehlcke L: linux-usb@vger.kernel.org S: Maintained -F: Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub -F: drivers/usb/misc/onboard_usb_hub.c +F: Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-dev +F: drivers/usb/misc/onboard_usb_dev.c ONENAND FLASH DRIVER M: Kyungmin Park @@ -18750,6 +18786,12 @@ F: Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml F: drivers/clk/clk-versaclock7.c +RENESAS PROXO CLOCK DRIVER +M: Alex Helms +S: Maintained +F: Documentation/devicetree/bindings/clock/renesas,proxo.yaml +F: drivers/clk/clk-proxo.c + RENESAS X9250 DIGITAL POTENTIOMETERS DRIVER M: Herve Codina L: linux-iio@vger.kernel.org @@ -24128,6 +24170,14 @@ F: Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml F: drivers/net/ethernet/xilinx/xilinx_axienet* +XILINX MEDIA AXIS SWITCH DRIVER +M: Anil kumar M +M: Karthikeyan T +L: git@xilinx.com +S: Maintained +F: Documentation/devicetree/bindings/media/xilinx/xlnx,axis-subsetconv.yaml +F: drivers/media/platform/xilinx/xilinx-axis-subsetconv.c + XILINX CAN DRIVER M: Appana Durga Kedareswara rao R: Naga Sureshkumar Relli @@ -24136,6 +24186,11 @@ F: Documentation/devicetree/bindings/net/can/xilinx,can.yaml F: drivers/net/can/xilinx_can.c +XILINX ECDSA DRIVER +M: Harsha +S: Maintained +F: drivers/crypto/xilinx/xilinx-ecdsa.c + XILINX EVENT MANAGEMENT DRIVER M: Abhyuday Godhasara S: Maintained @@ -24167,13 +24222,44 @@ M: Derek Kiernan M: Dragan Cvetic S: Maintained -F: Documentation/devicetree/bindings/misc/xlnx,sd-fec.txt +F: Documentation/devicetree/bindings/misc/xlnx,sd-fec.yaml F: Documentation/misc-devices/xilinx_sdfec.rst F: drivers/misc/Kconfig F: drivers/misc/Makefile F: drivers/misc/xilinx_sdfec.c F: include/uapi/misc/xilinx_sdfec.h +XILINX PUF driver +M: Kundanala Praveen Teja +R: Michal Simek +S: Maintained +F: drivers/misc/xilinx_puf.c +F: include/uapi/misc/xilinx_puf.h + +XILINX VERSAL SYSMON DRIVER +M: Salih Erim +R: Dragan Cvetic +L: git@xilinx.com +S: Maintained +F: Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml +F: drivers/iio/adc/versal-sysmon.c +F: drivers/iio/adc/versal-sysmon.h +F: include/linux/iio/adc/versal-sysmon-events.h + +XILINX VERSAL SECURE CONFIGURATION DRIVER +M: Harsha +R: Michal Simek +S: Maintained +F: Documentation/devicetree/bindings/nvmem/xlnx,versal-sec-cfg.yaml +F: drivers/nvmem/xlnx_secure_config.c + +XILINX VERSAL THERMAL DRIVER +M: Salih Erim +R: Dragan Cvetic +S: Maintained +F: Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.yaml +F: drivers/thermal/versal_thermal.c + XILINX UARTLITE SERIAL DRIVER M: Peter Korsgaard L: linux-serial@vger.kernel.org @@ -24245,6 +24331,12 @@ S: Maintained F: drivers/crypto/xilinx/zynqmp-sha.c +XILINX VERSAL XILSEM EDAC DRIVER +M: Rama Devi Veggalam +S: Maintained +F: Documentation/devicetree/bindings/edac/xlnx,versal-xilsem-edac.yaml +F: drivers/edac/xilinx_xilsem_edac.c + XILLYBUS DRIVER M: Eli Billauer L: linux-kernel@vger.kernel.org --- linux-xilinx-6.8.0.orig/Makefile +++ linux-xilinx-6.8.0/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 8 -SUBLEVEL = 0 +SUBLEVEL = 12 EXTRAVERSION = NAME = Hurr durr I'ma ninja sloth @@ -549,6 +549,9 @@ -I$(objtree)/include \ $(USERINCLUDE) +# UBUNTU: Include our third party driver stuff too +LINUXINCLUDE += -I$(srctree)/ubuntu/include + KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE KBUILD_CFLAGS := @@ -943,7 +946,6 @@ ifdef CONFIG_LTO_CLANG ifdef CONFIG_LTO_CLANG_THIN CC_FLAGS_LTO := -flto=thin -fsplit-lto-unit -KBUILD_LDFLAGS += --thinlto-cache-dir=$(extmod_prefix).thinlto-cache else CC_FLAGS_LTO := -flto endif @@ -1278,8 +1280,9 @@ quiet_cmd_headers_install = INSTALL $(INSTALL_HDR_PATH)/include cmd_headers_install = \ mkdir -p $(INSTALL_HDR_PATH); \ - rsync -mrl --include='*/' --include='*\.h' --exclude='*' \ - usr/include $(INSTALL_HDR_PATH) + find usr/include -type f -name '*.h' -print0 | \ + tar -czf - --null --no-recursion --no-wildcards-match-slash -T- | \ + tar -xzf - --strip-components=1 -C $(INSTALL_HDR_PATH) PHONY += headers_install headers_install: headers @@ -1294,6 +1297,7 @@ $(if $(filter um, $(SRCARCH)), $(error Headers not exportable for UML)) $(Q)$(MAKE) $(hdr-inst)=include/uapi $(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi + $(Q)$(MAKE) $(hdr-inst)=ubuntu/include dst=include oldheaders= ifdef CONFIG_HEADERS_INSTALL prepare: headers @@ -1479,13 +1483,13 @@ # Directories & files removed with 'make clean' CLEAN_FILES += vmlinux.symvers modules-only.symvers \ modules.builtin modules.builtin.modinfo modules.nsdeps \ - compile_commands.json .thinlto-cache rust/test \ + compile_commands.json rust/test \ rust-project.json .vmlinux.objs .vmlinux.export.c # Directories & files removed with 'make mrproper' MRPROPER_FILES += include/config include/generated \ arch/$(SRCARCH)/include/generated .objdiff \ - debian snap tar-install \ + snap tar-install \ .config .config.old .version \ Module.symvers \ certs/signing_key.pem \ @@ -1785,7 +1789,7 @@ clean-dirs := $(KBUILD_EXTMOD) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ - $(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache + $(KBUILD_EXTMOD)/compile_commands.json PHONY += prepare # now expand this into a simple variable to reduce the cost of shell evaluations --- linux-xilinx-6.8.0.orig/Ubuntu.md +++ linux-xilinx-6.8.0/Ubuntu.md @@ -0,0 +1,8 @@ +Name: linux-xilinx +Version: 6.8.0 +Series: 24.04 (noble) +Description: + This is the source code for the Ubuntu linux kernel for the 24.04 series. This + source tree is used to produce the flavours: xilinx. + This kernel is configured to support the widest range of desktop, laptop and + server configurations. --- linux-xilinx-6.8.0.orig/arch/Kconfig +++ linux-xilinx-6.8.0/arch/Kconfig @@ -9,6 +9,14 @@ # source "arch/$(SRCARCH)/Kconfig" +config ARCH_CONFIGURES_CPU_MITIGATIONS + bool + +if !ARCH_CONFIGURES_CPU_MITIGATIONS +config CPU_MITIGATIONS + def_bool y +endif + menu "General architecture-dependent options" config ARCH_HAS_SUBPAGE_FAULTS --- linux-xilinx-6.8.0.orig/arch/arc/boot/dts/hsdk.dts +++ linux-xilinx-6.8.0/arch/arc/boot/dts/hsdk.dts @@ -205,7 +205,6 @@ }; gmac: ethernet@8000 { - #interrupt-cells = <1>; compatible = "snps,dwmac"; reg = <0x8000 0x2000>; interrupts = <10>; --- linux-xilinx-6.8.0.orig/arch/arm/Kconfig +++ linux-xilinx-6.8.0/arch/arm/Kconfig @@ -29,7 +29,7 @@ select ARCH_HAVE_NMI_SAFE_CMPXCHG if CPU_V7 || CPU_V7M || CPU_V6K select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_KEEP_MEMBLOCK - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7 @@ -503,8 +503,8 @@ config IWMMXT bool "Enable iWMMXt support" - depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B - default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B + depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK + default y if PXA27x || PXA3xx || ARCH_MMP help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. --- linux-xilinx-6.8.0.orig/arch/arm/Makefile +++ linux-xilinx-6.8.0/arch/arm/Makefile @@ -59,6 +59,9 @@ # KBUILD_CFLAGS += $(call cc-option,-fno-ipa-sra) +# Need -msoft-float for gcc 11 for the below instruction set selection +KBUILD_CFLAGS += -msoft-float + # This selects which instruction set is used. arch-$(CONFIG_CPU_32v7M) :=-march=armv7-m arch-$(CONFIG_CPU_32v7) :=-march=armv7-a @@ -141,7 +144,7 @@ # Need -Uarm for gcc < 3.x KBUILD_CPPFLAGS +=$(cpp-y) -KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm +KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -Uarm KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) -include asm/unified.h -msoft-float CHECKFLAGS += -D__arm__ --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/arm/arm-realview-pb1176.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/arm/arm-realview-pb1176.dts @@ -451,7 +451,7 @@ /* Direct-mapped development chip ROM */ pb1176_rom@10200000 { - compatible = "direct-mapped"; + compatible = "mtd-rom"; reg = <0x10200000 0x4000>; bank-width = <1>; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/marvell/mmp2-brownstone.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/marvell/mmp2-brownstone.dts @@ -28,7 +28,7 @@ &twsi1 { status = "okay"; pmic: max8925@3c { - compatible = "maxium,max8925"; + compatible = "maxim,max8925"; reg = <0x3c>; interrupts = <1>; interrupt-parent = <&intcmux4>; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/microchip/at91-sama7g5ek.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/microchip/at91-sama7g5ek.dts @@ -293,7 +293,7 @@ regulator-state-standby { regulator-on-in-suspend; - regulator-suspend-voltage = <1150000>; + regulator-suspend-microvolt = <1150000>; regulator-mode = <4>; }; @@ -314,7 +314,7 @@ regulator-state-standby { regulator-on-in-suspend; - regulator-suspend-voltage = <1050000>; + regulator-suspend-microvolt = <1050000>; regulator-mode = <4>; }; @@ -331,7 +331,7 @@ regulator-always-on; regulator-state-standby { - regulator-suspend-voltage = <1800000>; + regulator-suspend-microvolt = <1800000>; regulator-on-in-suspend; }; @@ -346,7 +346,7 @@ regulator-max-microvolt = <3700000>; regulator-state-standby { - regulator-suspend-voltage = <1800000>; + regulator-suspend-microvolt = <1800000>; regulator-on-in-suspend; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi @@ -117,17 +117,9 @@ #address-cells = <1>; #size-cells = <0>; - phy_port2: phy@1 { - reg = <1>; - }; - - phy_port3: phy@2 { - reg = <2>; - }; - switch@10 { compatible = "qca,qca8334"; - reg = <10>; + reg = <0x10>; reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; switch_ports: ports { @@ -149,15 +141,30 @@ eth2: port@2 { reg = <2>; label = "eth2"; + phy-mode = "internal"; phy-handle = <&phy_port2>; }; eth1: port@3 { reg = <3>; label = "eth1"; + phy-mode = "internal"; phy-handle = <&phy_port3>; }; }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy_port2: ethernet-phy@1 { + reg = <1>; + }; + + phy_port3: ethernet-phy@2 { + reg = <2>; + }; + }; }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-common.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-common.dtsi @@ -805,6 +805,7 @@ &pinctrl_usb_pwr>; dr_mode = "host"; power-active-high; + over-current-active-low; disable-over-current; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts @@ -210,6 +210,7 @@ remote-endpoint = <&mipi_from_sensor>; clock-lanes = <0>; data-lanes = <1>; + link-frequencies = /bits/ 64 <330000000>; }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi @@ -1234,7 +1234,7 @@ qfprom: qfprom@fc4bc000 { compatible = "qcom,msm8974-qfprom", "qcom,qfprom"; - reg = <0xfc4bc000 0x1000>; + reg = <0xfc4bc000 0x2100>; #address-cells = <1>; #size-cells = <1>; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts @@ -209,6 +209,18 @@ status = "okay"; }; +&extal1_clk { + clock-frequency = <26000000>; +}; + +&extal2_clk { + clock-frequency = <48000000>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + &pfc { scifa0_pins: scifa0 { groups = "scifa0_data"; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/renesas/r8a73a4.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/renesas/r8a73a4.dtsi @@ -450,17 +450,20 @@ extalr_clk: extalr { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <32768>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; }; extal1_clk: extal1 { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <25000000>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; }; extal2_clk: extal2 { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <48000000>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; }; fsiack_clk: fsiack { compatible = "fixed-clock"; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/rockchip/rk3066a.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/rockchip/rk3066a.dtsi @@ -128,6 +128,7 @@ pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>; power-domains = <&power RK3066_PD_VIO>; rockchip,grf = <&grf>; + #sound-dai-cells = <0>; status = "disabled"; ports { --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/rockchip/rk322x.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/rockchip/rk322x.dtsi @@ -736,14 +736,20 @@ status = "disabled"; ports { - hdmi_in: port { - #address-cells = <1>; - #size-cells = <0>; - hdmi_in_vop: endpoint@0 { - reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; + + hdmi_in_vop: endpoint { remote-endpoint = <&vop_out_hdmi>; }; }; + + hdmi_out: port@1 { + reg = <1>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/rockchip/rk3288.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/rockchip/rk3288.dtsi @@ -1240,27 +1240,37 @@ compatible = "rockchip,rk3288-dw-hdmi"; reg = <0x0 0xff980000 0x0 0x20000>; reg-io-width = <4>; - #sound-dai-cells = <0>; - rockchip,grf = <&grf>; interrupts = ; clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>; clock-names = "iahb", "isfr", "cec"; power-domains = <&power RK3288_PD_VIO>; + rockchip,grf = <&grf>; + #sound-dai-cells = <0>; status = "disabled"; ports { - hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; #address-cells = <1>; #size-cells = <0>; + hdmi_in_vopb: endpoint@0 { reg = <0>; remote-endpoint = <&vopb_out_hdmi>; }; + hdmi_in_vopl: endpoint@1 { reg = <1>; remote-endpoint = <&vopl_out_hdmi>; }; }; + + hdmi_out: port@1 { + reg = <1>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts @@ -88,7 +88,7 @@ &keypad { samsung,keypad-num-rows = <2>; samsung,keypad-num-columns = <8>; - linux,keypad-no-autorepeat; + linux,input-no-autorepeat; wakeup-source; pinctrl-names = "default"; pinctrl-0 = <&keypad_rows &keypad_cols>; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/samsung/exynos4412-origen.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/samsung/exynos4412-origen.dts @@ -453,7 +453,7 @@ &keypad { samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <2>; - linux,keypad-no-autorepeat; + linux,input-no-autorepeat; wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts @@ -69,7 +69,7 @@ &keypad { samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <8>; - linux,keypad-no-autorepeat; + linux,input-no-autorepeat; wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-7000.dtsi +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-7000.dtsi @@ -1,6 +1,9 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2011 - 2014 Xilinx + * Xilinx Zynq 7000 DTSI + * Describes the hardware common to all Zynq 7000-based boards. + * + * Copyright (C) 2011 - 2015 Xilinx */ / { @@ -8,6 +11,13 @@ #size-cells = <1>; compatible = "xlnx,zynq-7000"; + options { + u-boot { + compatible = "u-boot,config"; + bootscr-address = /bits/ 64 <0x3000000>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -34,7 +44,7 @@ }; }; - fpga_full: fpga-full { + fpga_full: fpga-region { compatible = "fpga-region"; fpga-mgr = <&devcfg>; #address-cells = <1>; @@ -93,6 +103,7 @@ }; amba: axi { + bootph-all; compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -190,6 +201,17 @@ reg = <0xf8006000 0x1000>; }; + ocm: sram@fffc0000 { + compatible = "mmio-sram"; + reg = <0xfffc0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xfffc0000 0x10000>; + ocm-sram@0 { + reg = <0x0 0x10000>; + }; + }; + uart0: serial@e0000000 { compatible = "xlnx,xuartps", "cdns,uart-r1p8"; status = "disabled"; @@ -277,13 +299,18 @@ 0x2 0x0 0xe4000000 0x2000000>; /* SRAM/NOR CS1 region */ #address-cells = <2>; #size-cells = <1>; + interrupt-parent = <&intc>; + interrupts = <0 18 4>; nfc0: nand-controller@0,0 { compatible = "arm,pl353-nand-r2p1"; reg = <0 0 0x1000000>; status = "disabled"; - #address-cells = <1>; - #size-cells = <0>; + }; + nor0: flash@1,0 { + status = "disabled"; + compatible = "cfi-flash"; + reg = <1 0 0x2000000>; }; }; @@ -308,15 +335,17 @@ }; slcr: slcr@f8000000 { + bootph-all; #address-cells = <1>; #size-cells = <1>; compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd"; reg = <0xF8000000 0x1000>; ranges; clkc: clkc@100 { + bootph-all; #clock-cells = <1>; compatible = "xlnx,ps7-clkc"; - fclk-enable = <0>; + fclk-enable = <0xf>; clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", "lqspi", "smc", "pcap", "gem0", "gem1", @@ -368,11 +397,16 @@ reg = <0xf8007000 0x100>; interrupt-parent = <&intc>; interrupts = <0 8 4>; - clocks = <&clkc 12>; - clock-names = "ref_clk"; + clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>; + clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; syscon = <&slcr>; }; + efuse: efuse@f800d000 { + compatible = "xlnx,zynq-efuse"; + reg = <0xf800d000 0x20>; + }; + global_timer: timer@f8f00200 { compatible = "arm,cortex-a9-global-timer"; reg = <0xf8f00200 0x20>; @@ -398,6 +432,7 @@ }; scutimer: timer@f8f00600 { + bootph-all; interrupt-parent = <&intc>; interrupts = <1 13 0x301>; compatible = "arm,cortex-a9-twd-timer"; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-cc108.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-cc108.dts @@ -18,6 +18,7 @@ aliases { ethernet0 = &gem0; serial0 = &uart0; + spi0 = &qspi; }; chosen { @@ -48,7 +49,44 @@ ethernet_phy: ethernet-phy@1 { reg = <1>; - device_type = "ethernet-phy"; + }; +}; + +&qspi { + status = "okay"; + num-cs = <1>; + flash@0 { /* 16 MB */ + compatible = "n25q128a11", "jedec,spi-nor"; + reg = <0x0>; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "qspi-fsbl-uboot-bs"; + reg = <0x0 0x400000>; /* 4MB */ + }; + partition@400000 { + label = "qspi-linux"; + reg = <0x400000 0x400000>; /* 4MB */ + }; + partition@800000 { + label = "qspi-rootfs"; + reg = <0x800000 0x400000>; /* 4MB */ + }; + partition@c00000 { + label = "qspi-devicetree"; + reg = <0xc00000 0x100000>; /* 1MB */ + }; + partition@d00000 { + label = "qspi-scratch"; + reg = <0xd00000 0x200000>; /* 2MB */ + }; + partition@f00000 { + label = "qspi-uboot-env"; + reg = <0xf00000 0x100000>; /* 1MB */ + }; }; }; @@ -59,6 +97,7 @@ }; &uart0 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-ebaz4205.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-ebaz4205.dts @@ -50,6 +50,8 @@ &nfc0 { status = "okay"; + #address-cells = <1>; + #size-cells = <0>; nand@0 { reg = <0>; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-parallella.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-parallella.dts @@ -46,7 +46,6 @@ compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22"; reg = <0>; - device_type = "ethernet-phy"; marvell,reg-init = <0x3 0x10 0xff00 0x1e>, <0x3 0x11 0xfff0 0xa>; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zc702.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zc702.dts @@ -1,6 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2011 - 2014 Xilinx + * Copyright (C) 2011 - 2015 Xilinx * Copyright (C) 2012 National Instruments Corp. */ /dts-v1/; @@ -15,7 +15,11 @@ ethernet0 = &gem0; i2c0 = &i2c0; serial0 = &uart1; + spi0 = &qspi; mmc0 = &sdhci0; + usb0 = &usb0; + nvmem0 = &eeprom; + rtc0 = &rtc; }; memory@0 { @@ -57,22 +61,12 @@ }; }; - usb_phy0: phy0 { - compatible = "usb-nop-xceiv"; + usb_phy0: phy0@e0002000 { + compatible = "ulpi-phy"; #phy-cells = <0>; - }; -}; - -&amba { - ocm: sram@fffc0000 { - compatible = "mmio-sram"; - reg = <0xfffc0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0xfffc0000 0x10000>; - ocm-sram@0 { - reg = <0x0 0x10000>; - }; + reg = <0xe0002000 0x1000>; + view-port = <0x0170>; + drv-vbus; }; }; @@ -92,10 +86,11 @@ phy-handle = <ðernet_phy>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem0_default>; + phy-reset-gpio = <&gpio0 11 0>; + phy-reset-active-low; ethernet_phy: ethernet-phy@7 { reg = <7>; - device_type = "ethernet-phy"; }; }; @@ -152,7 +147,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - eeprom@54 { + eeprom: eeprom@54 { compatible = "atmel,24c08"; reg = <0x54>; }; @@ -174,7 +169,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - rtc@51 { + rtc: rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; @@ -210,7 +205,7 @@ conf { groups = "can0_9_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-rx { @@ -233,7 +228,7 @@ conf { groups = "ethernet0_0_grp"; slew-rate = <0>; - io-standard = <4>; + power-source = <4>; }; conf-rx { @@ -256,7 +251,7 @@ conf-mdio { groups = "mdio0_0_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; bias-disable; }; }; @@ -274,7 +269,7 @@ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp", "gpio0_13_grp", "gpio0_14_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-pull-up { @@ -298,11 +293,11 @@ groups = "i2c0_10_grp"; bias-pull-up; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; }; - pinctrl_i2c0_gpio: i2c0-gpio { + pinctrl_i2c0_gpio: i2c0-gpio-grp { mux { groups = "gpio0_50_grp", "gpio0_51_grp"; function = "gpio0"; @@ -311,7 +306,7 @@ conf { groups = "gpio0_50_grp", "gpio0_51_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; }; @@ -324,7 +319,7 @@ conf { groups = "sdio0_2_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; bias-disable; }; @@ -338,7 +333,7 @@ bias-high-impedance; bias-pull-up; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; mux-wp { @@ -351,7 +346,7 @@ bias-high-impedance; bias-pull-up; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; }; @@ -364,7 +359,7 @@ conf { groups = "uart1_10_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-rx { @@ -387,7 +382,7 @@ conf { groups = "usb0_0_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-rx { @@ -403,13 +398,53 @@ }; }; +&qspi { + bootph-all; + status = "okay"; + num-cs = <1>; + flash@0 { + compatible = "n25q128a11", "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { + label = "qspi-rootfs"; + reg = <0x620000 0x5e0000>; + }; + partition@c00000 { + label = "qspi-bitstream"; + reg = <0xc00000 0x400000>; + }; + }; + }; +}; + &sdhci0 { + bootph-all; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sdhci0_default>; }; &uart1 { + bootph-all; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1_default>; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zc706.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zc706.dts @@ -1,6 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2011 - 2014 Xilinx + * Copyright (C) 2011 - 2015 Xilinx * Copyright (C) 2012 National Instruments Corp. */ /dts-v1/; @@ -14,7 +14,10 @@ ethernet0 = &gem0; i2c0 = &i2c0; serial0 = &uart1; + spi0 = &qspi; mmc0 = &sdhci0; + nvmem0 = &eeprom; + rtc0 = &rtc; }; memory@0 { @@ -27,9 +30,12 @@ stdout-path = "serial0:115200n8"; }; - usb_phy0: phy0 { - compatible = "usb-nop-xceiv"; + usb_phy0: phy0@e0002000 { + compatible = "ulpi-phy"; #phy-cells = <0>; + reg = <0xe0002000 0x1000>; + view-port = <0x0170>; + drv-vbus; }; }; @@ -46,7 +52,6 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; - device_type = "ethernet-phy"; }; }; @@ -100,7 +105,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - eeprom@54 { + eeprom: eeprom@54 { compatible = "atmel,24c08"; reg = <0x54>; }; @@ -122,7 +127,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - rtc@51 { + rtc: rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; @@ -150,7 +155,7 @@ conf { groups = "ethernet0_0_grp"; slew-rate = <0>; - io-standard = <4>; + power-source = <4>; }; conf-rx { @@ -173,7 +178,7 @@ conf-mdio { groups = "mdio0_0_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; bias-disable; }; }; @@ -187,7 +192,7 @@ conf { groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-pull-up { @@ -211,7 +216,7 @@ groups = "i2c0_10_grp"; bias-pull-up; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; }; @@ -224,7 +229,7 @@ conf { groups = "sdio0_2_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; bias-disable; }; @@ -238,7 +243,7 @@ bias-high-impedance; bias-pull-up; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; mux-wp { @@ -251,7 +256,7 @@ bias-high-impedance; bias-pull-up; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; }; @@ -264,7 +269,7 @@ conf { groups = "uart1_10_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-rx { @@ -287,7 +292,7 @@ conf { groups = "usb0_0_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = <1>; }; conf-rx { @@ -303,13 +308,54 @@ }; }; +&qspi { + bootph-all; + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "n25q128a11", "jedec,spi-nor"; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x1000000 0x1000000>; /* 16MB */ + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { + label = "qspi-rootfs"; + reg = <0x620000 0x5e0000>; + }; + partition@c00000 { + label = "qspi-bitstream"; + reg = <0xc00000 0x400000>; + }; + }; + }; +}; + &sdhci0 { + bootph-all; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sdhci0_default>; }; &uart1 { + bootph-all; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1_default>; @@ -322,3 +368,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0_default>; }; + +&watchdog0 { + reset-on-timeout; +}; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zc770-xm010.dts @@ -15,6 +15,7 @@ ethernet0 = &gem0; i2c0 = &i2c0; serial0 = &uart1; + spi0 = &qspi; spi1 = &spi1; }; @@ -45,7 +46,6 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; - device_type = "ethernet-phy"; }; }; @@ -57,7 +57,43 @@ compatible = "atmel,24c02"; reg = <0x52>; }; +}; +&qspi { + status = "okay"; + num-cs = <1>; + flash@0 { + compatible = "n25q128a11", "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { + label = "qspi-rootfs"; + reg = <0x620000 0x5e0000>; + }; + partition@c00000 { + label = "qspi-bitstream"; + reg = <0xc00000 0x400000>; + }; + }; + }; }; &sdhci0 { @@ -85,6 +121,7 @@ }; &uart1 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zc770-xm011.dts @@ -47,6 +47,36 @@ }; }; +&nfc0 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + nand@0 { + reg = <0>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "nand-fsbl-uboot"; + reg = <0x0 0x1000000>; + }; + partition@1000000 { + label = "nand-linux"; + reg = <0x1000000 0x2000000>; + }; + partition@3000000 { + label = "nand-rootfs"; + reg = <0x3000000 0x200000>; + }; + }; + }; +}; + +&smcc { + status = "okay"; +}; + &spi0 { status = "okay"; num-cs = <4>; @@ -54,6 +84,7 @@ }; &uart1 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zc770-xm012.dts @@ -53,6 +53,40 @@ }; }; +&nor0 { + status = "okay"; + bank-width = <1>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "nor-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { + label = "nor-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { + label = "nor-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { + label = "nor-rootfs"; + reg = <0x620000 0x5e0000>; + }; + partition@c00000 { + label = "nor-bitstream"; + reg = <0xc00000 0x400000>; + }; + }; +}; + +&smcc { + status = "okay"; +}; + &spi1 { status = "okay"; num-cs = <4>; @@ -60,5 +94,6 @@ }; &uart1 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zc770-xm013.dts @@ -15,6 +15,7 @@ ethernet0 = &gem1; i2c0 = &i2c1; serial0 = &uart0; + spi0 = &qspi; spi1 = &spi0; }; @@ -40,7 +41,6 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; - device_type = "ethernet-phy"; }; }; @@ -58,6 +58,44 @@ }; }; +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "n25q128a11", "jedec,spi-nor"; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x1000000 0x1000000>; /* 16MB */ + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { + label = "qspi-rootfs"; + reg = <0x620000 0x5e0000>; + }; + partition@c00000 { + label = "qspi-bitstream"; + reg = <0xc00000 0x400000>; + }; + }; + }; +}; + &spi0 { status = "okay"; num-cs = <4>; @@ -73,5 +111,6 @@ }; &uart0 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zed.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zed.dts @@ -1,6 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2011 - 2014 Xilinx + * Copyright (C) 2011 - 2015 Xilinx * Copyright (C) 2012 National Instruments Corp. */ /dts-v1/; @@ -13,6 +13,7 @@ aliases { ethernet0 = &gem0; serial0 = &uart1; + spi0 = &qspi; mmc0 = &sdhci0; }; @@ -26,9 +27,12 @@ stdout-path = "serial0:115200n8"; }; - usb_phy0: phy0 { - compatible = "usb-nop-xceiv"; + usb_phy0: phy0@e0002000 { + compatible = "ulpi-phy"; #phy-cells = <0>; + reg = <0xe0002000 0x1000>; + view-port = <0x0170>; + drv-vbus; }; }; @@ -43,15 +47,55 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; - device_type = "ethernet-phy"; + }; +}; + +&qspi { + bootph-all; + status = "okay"; + num-cs = <1>; + flash@0 { + compatible = "spansion,s25fl256s1", "jedec,spi-nor"; + reg = <0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + m25p,fast-read; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { + label = "qspi-rootfs"; + reg = <0x620000 0x5e0000>; + }; + partition@c00000 { + label = "qspi-bitstream"; + reg = <0xc00000 0x400000>; + }; + }; }; }; &sdhci0 { + bootph-all; status = "okay"; }; &uart1 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zybo-z7.dts @@ -49,7 +49,6 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; - device_type = "ethernet-phy"; }; }; --- linux-xilinx-6.8.0.orig/arch/arm/boot/dts/xilinx/zynq-zybo.dts +++ linux-xilinx-6.8.0/arch/arm/boot/dts/xilinx/zynq-zybo.dts @@ -1,6 +1,6 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2011 - 2014 Xilinx + * Copyright (C) 2011 - 2015 Xilinx * Copyright (C) 2012 National Instruments Corp. */ /dts-v1/; @@ -13,6 +13,7 @@ aliases { ethernet0 = &gem0; serial0 = &uart1; + spi0 = &qspi; mmc0 = &sdhci0; }; @@ -44,15 +45,21 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; - device_type = "ethernet-phy"; }; }; +&qspi { + bootph-all; + status = "okay"; +}; + &sdhci0 { + bootph-all; status = "okay"; }; &uart1 { + bootph-all; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm/configs/sunxi_defconfig +++ linux-xilinx-6.8.0/arch/arm/configs/sunxi_defconfig @@ -110,6 +110,7 @@ CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_PANEL_EDP=y CONFIG_DRM_SIMPLE_BRIDGE=y +CONFIG_DRM_DW_HDMI=y CONFIG_DRM_LIMA=y CONFIG_FB_SIMPLE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y --- linux-xilinx-6.8.0.orig/arch/arm/configs/xilinx_zynq_defconfig +++ linux-xilinx-6.8.0/arch/arm/configs/xilinx_zynq_defconfig @@ -0,0 +1,229 @@ +CONFIG_LOCALVERSION="-xilinx" +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +# CONFIG_BUG is not set +CONFIG_PERF_EVENTS=y +CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_ZYNQ=y +CONFIG_PL310_ERRATA_588369=y +CONFIG_PL310_ERRATA_727915=y +CONFIG_PL310_ERRATA_769419=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_754327=y +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_BIG_LITTLE=y +CONFIG_BL_SWITCHER=y +CONFIG_HIGHMEM=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_ZYNQ_CPUIDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_GCC_PLUGINS is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_COMPACTION is not set +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_SYN_COOKIES=y +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_CAN=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCIE_XILINX=y +CONFIG_UEVENT_HELPER=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_PL35X=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_NETDEVICES=y +CONFIG_MACB=y +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +CONFIG_E1000E=y +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_R8169=y +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_XILINX_EMACLITE=y +CONFIG_XILINX_AXI_EMAC=y +CONFIG_MARVELL_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_CAN_XILINXCAN=y +CONFIG_MDIO_BITBANG=y +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_CADENCE=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_XILINX=y +CONFIG_SPI_ZYNQ_QSPI=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_XILINX=y +CONFIG_GPIO_ZYNQ=y +CONFIG_PMBUS=y +CONFIG_SENSORS_UCD9000=y +CONFIG_SENSORS_UCD9200=y +CONFIG_THERMAL=y +CONFIG_CPU_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_XILINX_WATCHDOG=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_REGULATOR=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_XILINX=y +CONFIG_VIDEO_XILINX_CFA=y +CONFIG_VIDEO_XILINX_CRESAMPLE=y +CONFIG_VIDEO_XILINX_REMAPPER=y +CONFIG_VIDEO_XILINX_RGB2YUV=y +CONFIG_VIDEO_XILINX_SCALER=y +CONFIG_VIDEO_XILINX_SWITCH=y +CONFIG_VIDEO_XILINX_TPG=y +CONFIG_VIDEO_ADV7604=y +CONFIG_DRM=y +CONFIG_DRM_XLNX=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_ADI=y +CONFIG_SND_SOC_ADI_AXI_I2S=y +CONFIG_SND_SOC_ADI_AXI_SPDIF=y +CONFIG_HID_MICROSOFT=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_XILINX=y +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_ZERO=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=y +CONFIG_LEDS_TRIGGER_CAMERA=y +CONFIG_EDAC=y +CONFIG_EDAC_SYNOPSYS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_PCF8563=y +CONFIG_DMADEVICES=y +CONFIG_PL330_DMA=y +CONFIG_XILINX_DMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y +CONFIG_UIO_XILINX_APM=y +CONFIG_COMMON_CLK_SI570=y +CONFIG_REMOTEPROC=y +CONFIG_ZYNQ_REMOTEPROC=m +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_XILINX_XADC=y +CONFIG_XILINX_INTC=y +CONFIG_RAS=y +CONFIG_FPGA=y +CONFIG_FPGA_MGR_ZYNQ_FPGA=y +CONFIG_FPGA_MGR_ZYNQ_AFI_FPGA=y +CONFIG_FPGA_BRIDGE=y +CONFIG_XILINX_PR_DECOUPLER=y +CONFIG_FPGA_REGION=y +CONFIG_OF_FPGA_REGION=y +CONFIG_EXT3_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_DMA_CMA=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_FTRACE is not set --- linux-xilinx-6.8.0.orig/arch/arm/crypto/sha256_glue.c +++ linux-xilinx-6.8.0/arch/arm/crypto/sha256_glue.c @@ -24,8 +24,8 @@ #include "sha256_glue.h" -asmlinkage void sha256_block_data_order(u32 *digest, const void *data, - unsigned int num_blks); +asmlinkage void sha256_block_data_order(struct sha256_state *state, + const u8 *data, int num_blks); int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data, unsigned int len) @@ -33,23 +33,20 @@ /* make sure casting to sha256_block_fn() is safe */ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0); - return sha256_base_do_update(desc, data, len, - (sha256_block_fn *)sha256_block_data_order); + return sha256_base_do_update(desc, data, len, sha256_block_data_order); } EXPORT_SYMBOL(crypto_sha256_arm_update); static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out) { - sha256_base_do_finalize(desc, - (sha256_block_fn *)sha256_block_data_order); + sha256_base_do_finalize(desc, sha256_block_data_order); return sha256_base_finish(desc, out); } int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { - sha256_base_do_update(desc, data, len, - (sha256_block_fn *)sha256_block_data_order); + sha256_base_do_update(desc, data, len, sha256_block_data_order); return crypto_sha256_arm_final(desc, out); } EXPORT_SYMBOL(crypto_sha256_arm_finup); --- linux-xilinx-6.8.0.orig/arch/arm/crypto/sha512-glue.c +++ linux-xilinx-6.8.0/arch/arm/crypto/sha512-glue.c @@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha384-arm"); MODULE_ALIAS_CRYPTO("sha512-arm"); -asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks); +asmlinkage void sha512_block_data_order(struct sha512_state *state, + u8 const *src, int blocks); int sha512_arm_update(struct shash_desc *desc, const u8 *data, unsigned int len) { - return sha512_base_do_update(desc, data, len, - (sha512_block_fn *)sha512_block_data_order); + return sha512_base_do_update(desc, data, len, sha512_block_data_order); } static int sha512_arm_final(struct shash_desc *desc, u8 *out) { - sha512_base_do_finalize(desc, - (sha512_block_fn *)sha512_block_data_order); + sha512_base_do_finalize(desc, sha512_block_data_order); return sha512_base_finish(desc, out); } int sha512_arm_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { - sha512_base_do_update(desc, data, len, - (sha512_block_fn *)sha512_block_data_order); + sha512_base_do_update(desc, data, len, sha512_block_data_order); return sha512_arm_final(desc, out); } --- linux-xilinx-6.8.0.orig/arch/arm/include/asm/mman.h +++ linux-xilinx-6.8.0/arch/arm/include/asm/mman.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_MMAN_H__ +#define __ASM_MMAN_H__ + +#include +#include + +static inline bool arch_memory_deny_write_exec_supported(void) +{ + return cpu_architecture() >= CPU_ARCH_ARMv6; +} +#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported + +#endif /* __ASM_MMAN_H__ */ --- linux-xilinx-6.8.0.orig/arch/arm/kernel/Makefile +++ linux-xilinx-6.8.0/arch/arm/kernel/Makefile @@ -75,8 +75,6 @@ obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o -obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o -obj-$(CONFIG_CPU_PJ4B) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \ --- linux-xilinx-6.8.0.orig/arch/arm/kernel/iwmmxt.S +++ linux-xilinx-6.8.0/arch/arm/kernel/iwmmxt.S @@ -18,18 +18,6 @@ #include #include "iwmmxt.h" -#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) -#define PJ4(code...) code -#define XSC(code...) -#elif defined(CONFIG_CPU_MOHAWK) || \ - defined(CONFIG_CPU_XSC3) || \ - defined(CONFIG_CPU_XSCALE) -#define PJ4(code...) -#define XSC(code...) code -#else -#error "Unsupported iWMMXt architecture" -#endif - #define MMX_WR0 (0x00) #define MMX_WR1 (0x08) #define MMX_WR2 (0x10) @@ -81,17 +69,13 @@ ENTRY(iwmmxt_task_enable) inc_preempt_count r10, r3 - XSC(mrc p15, 0, r2, c15, c1, 0) - PJ4(mrc p15, 0, r2, c1, c0, 2) + mrc p15, 0, r2, c15, c1, 0 @ CP0 and CP1 accessible? - XSC(tst r2, #0x3) - PJ4(tst r2, #0xf) + tst r2, #0x3 bne 4f @ if so no business here @ enable access to CP0 and CP1 - XSC(orr r2, r2, #0x3) - XSC(mcr p15, 0, r2, c15, c1, 0) - PJ4(orr r2, r2, #0xf) - PJ4(mcr p15, 0, r2, c1, c0, 2) + orr r2, r2, #0x3 + mcr p15, 0, r2, c15, c1, 0 ldr r3, =concan_owner ldr r2, [r0, #S_PC] @ current task pc value @@ -218,12 +202,9 @@ bne 1f @ no: quit @ enable access to CP0 and CP1 - XSC(mrc p15, 0, r4, c15, c1, 0) - XSC(orr r4, r4, #0x3) - XSC(mcr p15, 0, r4, c15, c1, 0) - PJ4(mrc p15, 0, r4, c1, c0, 2) - PJ4(orr r4, r4, #0xf) - PJ4(mcr p15, 0, r4, c1, c0, 2) + mrc p15, 0, r4, c15, c1, 0 + orr r4, r4, #0x3 + mcr p15, 0, r4, c15, c1, 0 mov r0, #0 @ nothing to load str r0, [r3] @ no more current owner @@ -232,10 +213,8 @@ bl concan_save @ disable access to CP0 and CP1 - XSC(bic r4, r4, #0x3) - XSC(mcr p15, 0, r4, c15, c1, 0) - PJ4(bic r4, r4, #0xf) - PJ4(mcr p15, 0, r4, c1, c0, 2) + bic r4, r4, #0x3 + mcr p15, 0, r4, c15, c1, 0 mrc p15, 0, r2, c2, c0, 0 mov r2, r2 @ cpwait @@ -330,11 +309,9 @@ */ ENTRY(iwmmxt_task_switch) - XSC(mrc p15, 0, r1, c15, c1, 0) - PJ4(mrc p15, 0, r1, c1, c0, 2) + mrc p15, 0, r1, c15, c1, 0 @ CP0 and CP1 accessible? - XSC(tst r1, #0x3) - PJ4(tst r1, #0xf) + tst r1, #0x3 bne 1f @ yes: block them for next task ldr r2, =concan_owner @@ -344,10 +321,8 @@ retne lr @ no: leave Concan disabled 1: @ flip Concan access - XSC(eor r1, r1, #0x3) - XSC(mcr p15, 0, r1, c15, c1, 0) - PJ4(eor r1, r1, #0xf) - PJ4(mcr p15, 0, r1, c1, c0, 2) + eor r1, r1, #0x3 + mcr p15, 0, r1, c15, c1, 0 mrc p15, 0, r1, c2, c0, 0 sub pc, lr, r1, lsr #32 @ cpwait and return --- linux-xilinx-6.8.0.orig/arch/arm/kernel/sleep.S +++ linux-xilinx-6.8.0/arch/arm/kernel/sleep.S @@ -127,6 +127,10 @@ instr_sync #endif bl cpu_init @ restore the und/abt/irq banked regs +#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK) + mov r0, sp + bl kasan_unpoison_task_stack_below +#endif mov r0, #0 @ return zero on success ldmfd sp!, {r4 - r11, pc} ENDPROC(cpu_resume_after_mmu) --- linux-xilinx-6.8.0.orig/arch/arm/mach-davinci/pm.c +++ linux-xilinx-6.8.0/arch/arm/mach-davinci/pm.c @@ -61,7 +61,7 @@ /* Configure sleep count in deep sleep register */ val = __raw_readl(pm_config.deepsleep_reg); - val &= ~DEEPSLEEP_SLEEPCOUNT_MASK, + val &= ~DEEPSLEEP_SLEEPCOUNT_MASK; val |= pm_config.sleepcount; __raw_writel(val, pm_config.deepsleep_reg); --- linux-xilinx-6.8.0.orig/arch/arm/mach-omap2/board-n8x0.c +++ linux-xilinx-6.8.0/arch/arm/mach-omap2/board-n8x0.c @@ -79,10 +79,8 @@ static struct gpiod_lookup_table tusb_gpio_table = { .dev_id = "musb-tusb", .table = { - GPIO_LOOKUP("gpio-0-15", 0, "enable", - GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-48-63", 10, "int", - GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-0-31", 0, "enable", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-32-63", 26, "int", GPIO_ACTIVE_HIGH), { } }, }; @@ -140,12 +138,11 @@ static int slot2_cover_open; static struct device *mmc_device; -static struct gpiod_lookup_table nokia8xx_mmc_gpio_table = { +static struct gpiod_lookup_table nokia800_mmc_gpio_table = { .dev_id = "mmci-omap.0", .table = { /* Slot switch, GPIO 96 */ - GPIO_LOOKUP("gpio-80-111", 16, - "switch", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-96-127", 0, "switch", GPIO_ACTIVE_HIGH), { } }, }; @@ -153,12 +150,12 @@ static struct gpiod_lookup_table nokia810_mmc_gpio_table = { .dev_id = "mmci-omap.0", .table = { + /* Slot switch, GPIO 96 */ + GPIO_LOOKUP("gpio-96-127", 0, "switch", GPIO_ACTIVE_HIGH), /* Slot index 1, VSD power, GPIO 23 */ - GPIO_LOOKUP_IDX("gpio-16-31", 7, - "vsd", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-0-31", 23, "vsd", 1, GPIO_ACTIVE_HIGH), /* Slot index 1, VIO power, GPIO 9 */ - GPIO_LOOKUP_IDX("gpio-0-15", 9, - "vio", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-0-31", 9, "vio", 1, GPIO_ACTIVE_HIGH), { } }, }; @@ -415,8 +412,6 @@ static void __init n8x0_mmc_init(void) { - gpiod_add_lookup_table(&nokia8xx_mmc_gpio_table); - if (board_is_n810()) { mmc1_data.slots[0].name = "external"; @@ -429,6 +424,8 @@ mmc1_data.slots[1].name = "internal"; mmc1_data.slots[1].ban_openended = 1; gpiod_add_lookup_table(&nokia810_mmc_gpio_table); + } else { + gpiod_add_lookup_table(&nokia800_mmc_gpio_table); } mmc1_data.nr_slots = 2; --- linux-xilinx-6.8.0.orig/arch/arm/mach-zynq/Makefile +++ linux-xilinx-6.8.0/arch/arm/mach-zynq/Makefile @@ -4,5 +4,5 @@ # # Common support -obj-y := common.o slcr.o pm.o +obj-y := common.o efuse.o slcr.o pm.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o --- linux-xilinx-6.8.0.orig/arch/arm/mach-zynq/common.c +++ linux-xilinx-6.8.0/arch/arm/mach-zynq/common.c @@ -176,6 +176,7 @@ static void __init zynq_irq_init(void) { + zynq_early_efuse_init(); zynq_early_slcr_init(); irqchip_init(); } --- linux-xilinx-6.8.0.orig/arch/arm/mach-zynq/common.h +++ linux-xilinx-6.8.0/arch/arm/mach-zynq/common.h @@ -17,6 +17,9 @@ extern void zynq_slcr_cpu_state_write(int cpu, bool die); extern u32 zynq_slcr_get_device_id(void); +extern bool zynq_efuse_cpu_state(int cpu); +extern int zynq_early_efuse_init(void); + #ifdef CONFIG_SMP extern char zynq_secondary_trampoline; extern char zynq_secondary_trampoline_jump; --- linux-xilinx-6.8.0.orig/arch/arm/mach-zynq/efuse.c +++ linux-xilinx-6.8.0/arch/arm/mach-zynq/efuse.c @@ -0,0 +1,78 @@ +/* + * Xilinx EFUSE driver + * + * Copyright (c) 2016 Xilinx Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include "common.h" + +#define EFUSE_STATUS_OFFSET 0x10 + +/* 0 means cpu1 is working, 1 means cpu1 is broken */ +#define EFUSE_STATUS_CPU_BIT BIT(7) + +void __iomem *zynq_efuse_base; + +/** + * zynq_efuse_cpu_state - Read/write cpu state + * @cpu: cpu number + * + * Return: true if cpu is running, false if cpu is broken + */ +bool zynq_efuse_cpu_state(int cpu) +{ + u32 state; + + if (!cpu) + return true; + + if (!zynq_efuse_base) + return true; + + state = readl(zynq_efuse_base + EFUSE_STATUS_OFFSET); + state &= EFUSE_STATUS_CPU_BIT; + + if (!state) + return true; + + return false; +} + +/** + * zynq_early_efuse_init - Early efuse init function + * + * Return: 0 on success, negative errno otherwise. + * + * Called very early during boot from platform code. + */ +int __init zynq_early_efuse_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-efuse"); + if (!np) { + pr_err("%s: no efuse node found\n", __func__); + return -1; + } + + zynq_efuse_base = of_iomap(np, 0); + if (!zynq_efuse_base) { + pr_err("%s: Unable to map I/O memory\n", __func__); + return -1; + } + + np->data = (__force void *)zynq_efuse_base; + + pr_info("%s mapped to %p\n", np->name, zynq_efuse_base); + + of_node_put(np); + + return 0; +} --- linux-xilinx-6.8.0.orig/arch/arm/mach-zynq/platsmp.c +++ linux-xilinx-6.8.0/arch/arm/mach-zynq/platsmp.c @@ -83,6 +83,9 @@ static int zynq_boot_secondary(unsigned int cpu, struct task_struct *idle) { + if (!zynq_efuse_cpu_state(cpu)) + return -1; + return zynq_cpun_start(__pa_symbol(secondary_startup_arm), cpu); } --- linux-xilinx-6.8.0.orig/arch/arm/mach-zynq/slcr.c +++ linux-xilinx-6.8.0/arch/arm/mach-zynq/slcr.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "common.h" /* register offsets */ --- linux-xilinx-6.8.0.orig/arch/arm/mm/flush.c +++ linux-xilinx-6.8.0/arch/arm/mm/flush.c @@ -296,6 +296,9 @@ return; folio = page_folio(pfn_to_page(pfn)); + if (folio_test_reserved(folio)) + return; + if (cache_is_vipt_aliasing()) mapping = folio_flush_mapping(folio); else --- linux-xilinx-6.8.0.orig/arch/arm/net/bpf_jit_32.c +++ linux-xilinx-6.8.0/arch/arm/net/bpf_jit_32.c @@ -871,16 +871,11 @@ } /* dst = src (4 bytes)*/ -static inline void emit_a32_mov_r(const s8 dst, const s8 src, const u8 off, - struct jit_ctx *ctx) { +static inline void emit_a32_mov_r(const s8 dst, const s8 src, struct jit_ctx *ctx) { const s8 *tmp = bpf2a32[TMP_REG_1]; s8 rt; rt = arm_bpf_get_reg32(src, tmp[0], ctx); - if (off && off != 32) { - emit(ARM_LSL_I(rt, rt, 32 - off), ctx); - emit(ARM_ASR_I(rt, rt, 32 - off), ctx); - } arm_bpf_put_reg32(dst, rt, ctx); } @@ -889,15 +884,15 @@ const s8 src[], struct jit_ctx *ctx) { if (!is64) { - emit_a32_mov_r(dst_lo, src_lo, 0, ctx); + emit_a32_mov_r(dst_lo, src_lo, ctx); if (!ctx->prog->aux->verifier_zext) /* Zero out high 4 bytes */ emit_a32_mov_i(dst_hi, 0, ctx); } else if (__LINUX_ARM_ARCH__ < 6 && ctx->cpu_architecture < CPU_ARCH_ARMv5TE) { /* complete 8 byte move */ - emit_a32_mov_r(dst_lo, src_lo, 0, ctx); - emit_a32_mov_r(dst_hi, src_hi, 0, ctx); + emit_a32_mov_r(dst_lo, src_lo, ctx); + emit_a32_mov_r(dst_hi, src_hi, ctx); } else if (is_stacked(src_lo) && is_stacked(dst_lo)) { const u8 *tmp = bpf2a32[TMP_REG_1]; @@ -917,17 +912,52 @@ static inline void emit_a32_movsx_r64(const bool is64, const u8 off, const s8 dst[], const s8 src[], struct jit_ctx *ctx) { const s8 *tmp = bpf2a32[TMP_REG_1]; - const s8 *rt; + s8 rs; + s8 rd; - rt = arm_bpf_get_reg64(dst, tmp, ctx); + if (is_stacked(dst_lo)) + rd = tmp[1]; + else + rd = dst_lo; + rs = arm_bpf_get_reg32(src_lo, rd, ctx); + /* rs may be one of src[1], dst[1], or tmp[1] */ + + /* Sign extend rs if needed. If off == 32, lower 32-bits of src are moved to dst and sign + * extension only happens in the upper 64 bits. + */ + if (off != 32) { + /* Sign extend rs into rd */ + emit(ARM_LSL_I(rd, rs, 32 - off), ctx); + emit(ARM_ASR_I(rd, rd, 32 - off), ctx); + } else { + rd = rs; + } + + /* Write rd to dst_lo + * + * Optimization: + * Assume: + * 1. dst == src and stacked. + * 2. off == 32 + * + * In this case src_lo was loaded into rd(tmp[1]) but rd was not sign extended as off==32. + * So, we don't need to write rd back to dst_lo as they have the same value. + * This saves us one str instruction. + */ + if (dst_lo != src_lo || off != 32) + arm_bpf_put_reg32(dst_lo, rd, ctx); - emit_a32_mov_r(dst_lo, src_lo, off, ctx); if (!is64) { if (!ctx->prog->aux->verifier_zext) /* Zero out high 4 bytes */ emit_a32_mov_i(dst_hi, 0, ctx); } else { - emit(ARM_ASR_I(rt[0], rt[1], 31), ctx); + if (is_stacked(dst_hi)) { + emit(ARM_ASR_I(tmp[0], rd, 31), ctx); + arm_bpf_put_reg32(dst_hi, tmp[0], ctx); + } else { + emit(ARM_ASR_I(dst_hi, rd, 31), ctx); + } } } @@ -2222,28 +2252,21 @@ /* If building the body of the JITed code fails somehow, * we fall back to the interpretation. */ - if (build_body(&ctx) < 0) { - image_ptr = NULL; - bpf_jit_binary_free(header); - prog = orig_prog; - goto out_imms; - } + if (build_body(&ctx) < 0) + goto out_free; build_epilogue(&ctx); /* 3.) Extra pass to validate JITed Code */ - if (validate_code(&ctx)) { - image_ptr = NULL; - bpf_jit_binary_free(header); - prog = orig_prog; - goto out_imms; - } + if (validate_code(&ctx)) + goto out_free; flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx)); if (bpf_jit_enable > 1) /* there are 2 passes here */ bpf_jit_dump(prog->len, image_size, 2, ctx.target); - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) + goto out_free; prog->bpf_func = (void *)ctx.target; prog->jited = 1; prog->jited_len = image_size; @@ -2260,5 +2283,11 @@ bpf_jit_prog_release_other(prog, prog == orig_prog ? tmp : orig_prog); return prog; + +out_free: + image_ptr = NULL; + bpf_jit_binary_free(header); + prog = orig_prog; + goto out_imms; } --- linux-xilinx-6.8.0.orig/arch/arm64/Kconfig +++ linux-xilinx-6.8.0/arch/arm64/Kconfig @@ -107,7 +107,7 @@ select ARCH_WANT_LD_ORPHAN_WARN select ARCH_WANTS_NO_INSTR select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARM_AMBA select ARM_ARCH_TIMER select ARM_GIC @@ -198,7 +198,7 @@ if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG && \ - !CC_OPTIMIZE_FOR_SIZE) + (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE)) select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ if DYNAMIC_FTRACE_WITH_ARGS select HAVE_SAMPLE_FTRACE_DIRECT @@ -1550,7 +1550,7 @@ # 64K | 29 | 16 | 13 | 13 | config ARCH_FORCE_MAX_ORDER int - default "13" if ARM64_64K_PAGES + default "13" if ARM64_64K_PAGES || (ARCH_THUNDER && ARM64_4K_PAGES) default "11" if ARM64_16K_PAGES default "10" help --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts @@ -291,6 +291,8 @@ }; &spdif { + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx_pin>; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi @@ -166,6 +166,8 @@ }; &spdif { + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx_pin>; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi @@ -406,6 +406,7 @@ function = "spi1"; }; + /omit-if-no-ref/ spdif_tx_pin: spdif-tx-pin { pins = "PH7"; function = "spdif"; @@ -655,10 +656,8 @@ clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>; clock-names = "apb", "spdif"; resets = <&ccu RST_BUS_SPDIF>; - dmas = <&dma 2>; - dma-names = "tx"; - pinctrl-names = "default"; - pinctrl-0 = <&spdif_tx_pin>; + dmas = <&dma 2>, <&dma 2>; + dma-names = "rx", "tx"; status = "disabled"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-s4.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/amlogic/meson-s4.dtsi @@ -65,10 +65,15 @@ #clock-cells = <0>; }; - pwrc: power-controller { - compatible = "amlogic,meson-s4-pwrc"; - #power-domain-cells = <1>; - status = "okay"; + firmware { + sm: secure-monitor { + compatible = "amlogic,meson-gxbb-sm"; + + pwrc: power-controller { + compatible = "amlogic,meson-s4-pwrc"; + #power-domain-cells = <1>; + }; + }; }; soc { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi @@ -227,9 +227,6 @@ brcm,num-gphy = <5>; brcm,num-rgmii-ports = <2>; - #address-cells = <1>; - #size-cells = <0>; - ports: ports { #address-cells = <1>; #size-cells = <0>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi @@ -41,7 +41,7 @@ interrupts = ; fsl,usbphy = <&usbphy1>; fsl,usbmisc = <&usbmisc1 0>; - clocks = <&usb2_lpcg 0>; + clocks = <&usb2_lpcg IMX_LPCG_CLK_6>; ahb-burst-config = <0x0>; tx-burst-size-dword = <0x10>; rx-burst-size-dword = <0x10>; @@ -58,7 +58,7 @@ usbphy1: usbphy@5b100000 { compatible = "fsl,imx7ulp-usbphy"; reg = <0x5b100000 0x1000>; - clocks = <&usb2_lpcg 1>; + clocks = <&usb2_lpcg IMX_LPCG_CLK_7>; power-domains = <&pd IMX_SC_R_USB_0_PHY>; status = "disabled"; }; @@ -67,8 +67,8 @@ interrupts = ; reg = <0x5b010000 0x10000>; clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>, - <&sdhc0_lpcg IMX_LPCG_CLK_0>, - <&sdhc0_lpcg IMX_LPCG_CLK_5>; + <&sdhc0_lpcg IMX_LPCG_CLK_5>, + <&sdhc0_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_0>; status = "disabled"; @@ -78,8 +78,8 @@ interrupts = ; reg = <0x5b020000 0x10000>; clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>, - <&sdhc1_lpcg IMX_LPCG_CLK_0>, - <&sdhc1_lpcg IMX_LPCG_CLK_5>; + <&sdhc1_lpcg IMX_LPCG_CLK_5>, + <&sdhc1_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_1>; fsl,tuning-start-tap = <20>; @@ -91,8 +91,8 @@ interrupts = ; reg = <0x5b030000 0x10000>; clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>, - <&sdhc2_lpcg IMX_LPCG_CLK_0>, - <&sdhc2_lpcg IMX_LPCG_CLK_5>; + <&sdhc2_lpcg IMX_LPCG_CLK_5>, + <&sdhc2_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "ahb", "per"; power-domains = <&pd IMX_SC_R_SDHC_2>; status = "disabled"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi @@ -27,8 +27,8 @@ #size-cells = <0>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&spi0_lpcg 0>, - <&spi0_lpcg 1>; + clocks = <&spi0_lpcg IMX_LPCG_CLK_0>, + <&spi0_lpcg IMX_LPCG_CLK_4>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_SPI_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <60000000>; @@ -43,8 +43,8 @@ #size-cells = <0>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&spi1_lpcg 0>, - <&spi1_lpcg 1>; + clocks = <&spi1_lpcg IMX_LPCG_CLK_0>, + <&spi1_lpcg IMX_LPCG_CLK_4>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_SPI_1 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <60000000>; @@ -59,8 +59,8 @@ #size-cells = <0>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&spi2_lpcg 0>, - <&spi2_lpcg 1>; + clocks = <&spi2_lpcg IMX_LPCG_CLK_0>, + <&spi2_lpcg IMX_LPCG_CLK_4>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_SPI_2 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <60000000>; @@ -75,8 +75,8 @@ #size-cells = <0>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&spi3_lpcg 0>, - <&spi3_lpcg 1>; + clocks = <&spi3_lpcg IMX_LPCG_CLK_0>, + <&spi3_lpcg IMX_LPCG_CLK_4>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_SPI_3 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <60000000>; @@ -144,8 +144,8 @@ compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm"; reg = <0x5a190000 0x1000>; interrupts = ; - clocks = <&adma_pwm_lpcg 1>, - <&adma_pwm_lpcg 0>; + clocks = <&adma_pwm_lpcg IMX_LPCG_CLK_4>, + <&adma_pwm_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "per"; assigned-clocks = <&clk IMX_SC_R_LCD_0_PWM_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; @@ -377,8 +377,8 @@ reg = <0x5a880000 0x10000>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&adc0_lpcg 0>, - <&adc0_lpcg 1>; + clocks = <&adc0_lpcg IMX_LPCG_CLK_0>, + <&adc0_lpcg IMX_LPCG_CLK_4>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_ADC_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; @@ -392,8 +392,8 @@ reg = <0x5a890000 0x10000>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&adc1_lpcg 0>, - <&adc1_lpcg 1>; + clocks = <&adc1_lpcg IMX_LPCG_CLK_0>, + <&adc1_lpcg IMX_LPCG_CLK_4>; clock-names = "per", "ipg"; assigned-clocks = <&clk IMX_SC_R_ADC_1 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; @@ -406,8 +406,8 @@ reg = <0x5a8d0000 0x10000>; interrupts = ; interrupt-parent = <&gic>; - clocks = <&can0_lpcg 1>, - <&can0_lpcg 0>; + clocks = <&can0_lpcg IMX_LPCG_CLK_4>, + <&can0_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "per"; assigned-clocks = <&clk IMX_SC_R_CAN_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <40000000>; @@ -427,8 +427,8 @@ * CAN1 shares CAN0's clock and to enable CAN0's clock it * has to be powered on. */ - clocks = <&can0_lpcg 1>, - <&can0_lpcg 0>; + clocks = <&can0_lpcg IMX_LPCG_CLK_4>, + <&can0_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "per"; assigned-clocks = <&clk IMX_SC_R_CAN_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <40000000>; @@ -448,8 +448,8 @@ * CAN2 shares CAN0's clock and to enable CAN0's clock it * has to be powered on. */ - clocks = <&can0_lpcg 1>, - <&can0_lpcg 0>; + clocks = <&can0_lpcg IMX_LPCG_CLK_4>, + <&can0_lpcg IMX_LPCG_CLK_0>; clock-names = "ipg", "per"; assigned-clocks = <&clk IMX_SC_R_CAN_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <40000000>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi @@ -25,8 +25,8 @@ compatible = "fsl,imx27-pwm"; reg = <0x5d000000 0x10000>; clock-names = "ipg", "per"; - clocks = <&pwm0_lpcg 4>, - <&pwm0_lpcg 1>; + clocks = <&pwm0_lpcg IMX_LPCG_CLK_6>, + <&pwm0_lpcg IMX_LPCG_CLK_1>; assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; #pwm-cells = <3>; @@ -38,8 +38,8 @@ compatible = "fsl,imx27-pwm"; reg = <0x5d010000 0x10000>; clock-names = "ipg", "per"; - clocks = <&pwm1_lpcg 4>, - <&pwm1_lpcg 1>; + clocks = <&pwm1_lpcg IMX_LPCG_CLK_6>, + <&pwm1_lpcg IMX_LPCG_CLK_1>; assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; #pwm-cells = <3>; @@ -51,8 +51,8 @@ compatible = "fsl,imx27-pwm"; reg = <0x5d020000 0x10000>; clock-names = "ipg", "per"; - clocks = <&pwm2_lpcg 4>, - <&pwm2_lpcg 1>; + clocks = <&pwm2_lpcg IMX_LPCG_CLK_6>, + <&pwm2_lpcg IMX_LPCG_CLK_1>; assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; #pwm-cells = <3>; @@ -64,8 +64,8 @@ compatible = "fsl,imx27-pwm"; reg = <0x5d030000 0x10000>; clock-names = "ipg", "per"; - clocks = <&pwm3_lpcg 4>, - <&pwm3_lpcg 1>; + clocks = <&pwm3_lpcg IMX_LPCG_CLK_6>, + <&pwm3_lpcg IMX_LPCG_CLK_1>; assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>; assigned-clock-rates = <24000000>; #pwm-cells = <3>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts @@ -294,8 +294,8 @@ pinctrl_i2c4: i2c4grp { fsl,pins = < - MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 - MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 + MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083 + MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083 >; }; @@ -313,19 +313,19 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140 - MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140 - MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140 - MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140 + MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0 + MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0 + MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0 + MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0 >; }; pinctrl_uart2: uart2grp { fsl,pins = < - MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 - MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 - MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 - MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 + MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0 + MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0 + MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0 + MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0 >; }; @@ -337,40 +337,40 @@ pinctrl_usdhc2: usdhc2grp { fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; }; pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; }; pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts @@ -279,8 +279,8 @@ pinctrl_i2c4: i2c4grp { fsl,pins = < - MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3 - MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3 + MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083 + MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083 >; }; @@ -292,19 +292,19 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140 - MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140 - MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140 - MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140 + MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0 + MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0 + MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0 + MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0 >; }; pinctrl_uart2: uart2grp { fsl,pins = < - MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140 - MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140 - MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140 - MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140 + MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0 + MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0 + MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0 + MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0 >; }; @@ -316,40 +316,40 @@ pinctrl_usdhc2: usdhc2grp { fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; }; pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194 + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; }; pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { fsl,pins = < - MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196 + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96 MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019 - MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi @@ -210,7 +210,7 @@ reg = <0x52>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rtc>; - interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_HIGH>; + interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_LOW>; trickle-diode-disable; }; }; @@ -252,8 +252,8 @@ pinctrl_i2c1: i2c1grp { fsl,pins = < - MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 - MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083 >; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi @@ -237,8 +237,8 @@ pinctrl_i2c1: i2c1grp { fsl,pins = < - MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 - MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083 >; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi @@ -47,17 +47,6 @@ gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; status = "okay"; }; - - reg_usb_otg1_vbus: regulator-usb-otg1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_reg_usb1_en>; - compatible = "regulator-fixed"; - regulator-name = "usb_otg1_vbus"; - gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; }; /* off-board header */ @@ -144,9 +133,10 @@ }; &usbotg1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1>; dr_mode = "otg"; over-current-active-low; - vbus-supply = <®_usb_otg1_vbus>; status = "okay"; }; @@ -204,14 +194,6 @@ >; }; - pinctrl_reg_usb1_en: regusb1grp { - fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x41 - MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141 - MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41 - >; - }; - pinctrl_spi2: spi2grp { fsl,pins = < MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 @@ -234,4 +216,11 @@ MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 >; }; + + pinctrl_usbotg1: usbotg1grp { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141 + MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41 + >; + }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi @@ -6,6 +6,7 @@ #include #include #include "imx8mm.dtsi" +#include "imx8mm-overdrive.dtsi" / { chosen { @@ -929,7 +930,7 @@ /* Verdin GPIO_9_DSI (pulled-up as active-low) */ pinctrl_gpio_9_dsi: gpio9dsigrp { fsl,pins = - ; /* SODIMM 17 */ + ; /* SODIMM 17 */ }; /* Verdin GPIO_10_DSI (pulled-up as active-low) */ --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts @@ -121,7 +121,7 @@ flash@0 { /* W25Q128JVEI */ compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <100000000>; /* Up to 133 MHz */ + spi-max-frequency = <40000000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi @@ -254,7 +254,7 @@ <&clk IMX8MP_CLK_CLKOUT2>, <&clk IMX8MP_AUDIO_PLL2_OUT>; assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; - assigned-clock-rates = <13000000>, <13000000>, <156000000>; + assigned-clock-rates = <13000000>, <13000000>, <208000000>; reset-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>; status = "disabled"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -23,7 +23,7 @@ port { hdmi_connector_in: endpoint { - remote-endpoint = <&adv7533_out>; + remote-endpoint = <&adv7535_out>; }; }; }; @@ -107,6 +107,13 @@ enable-active-high; }; + reg_vext_3v3: regulator-vext-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VEXT_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + sound { compatible = "simple-audio-card"; simple-audio-card,name = "wm8960-audio"; @@ -364,7 +371,7 @@ regulator-always-on; }; - BUCK5 { + reg_buck5: BUCK5 { regulator-name = "BUCK5"; regulator-min-microvolt = <1650000>; regulator-max-microvolt = <1950000>; @@ -415,14 +422,16 @@ hdmi@3d { compatible = "adi,adv7535"; - reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>; - reg-names = "main", "cec", "edid", "packet"; + reg = <0x3d>; + interrupt-parent = <&gpio1>; + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; adi,dsi-lanes = <4>; - adi,input-depth = <8>; - adi,input-colorspace = "rgb"; - adi,input-clock = "1x"; - adi,input-style = <1>; - adi,input-justification = "evenly"; + avdd-supply = <®_buck5>; + dvdd-supply = <®_buck5>; + pvdd-supply = <®_buck5>; + a2vdd-supply = <®_buck5>; + v3p3-supply = <®_vext_3v3>; + v1p2-supply = <®_buck5>; ports { #address-cells = <1>; @@ -431,7 +440,7 @@ port@0 { reg = <0>; - adv7533_in: endpoint { + adv7535_in: endpoint { remote-endpoint = <&dsi_out>; }; }; @@ -439,7 +448,7 @@ port@1 { reg = <1>; - adv7533_out: endpoint { + adv7535_out: endpoint { remote-endpoint = <&hdmi_connector_in>; }; }; @@ -524,7 +533,7 @@ reg = <1>; dsi_out: endpoint { - remote-endpoint = <&adv7533_in>; + remote-endpoint = <&adv7535_in>; data-lanes = <1 2 3 4>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi @@ -14,6 +14,7 @@ pinctrl-0 = <&pinctrl_usbcon1>; type = "micro"; label = "otg"; + vbus-supply = <®_usb1_vbus>; id-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; port { @@ -183,7 +184,6 @@ }; &usb3_phy0 { - vbus-supply = <®_usb1_vbus>; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi @@ -14,6 +14,7 @@ pinctrl-0 = <&pinctrl_usbcon1>; type = "micro"; label = "otg"; + vbus-supply = <®_usb1_vbus>; id-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; port { @@ -182,7 +183,7 @@ bluetooth { compatible = "brcm,bcm4330-bt"; - shutdown-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; }; }; @@ -202,7 +203,6 @@ }; &usb3_phy0 { - vbus-supply = <®_usb1_vbus>; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8qm-mek.dts @@ -36,7 +36,7 @@ regulator-name = "SD1_SPWR"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; - gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>; + gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>; enable-active-high; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi @@ -96,15 +96,30 @@ status = "okay"; }; +/* It is eDMA1 in 8QM RM, but 8QXP it is eDMA3 */ &edma3 { + reg = <0x5a9f0000 0x210000>; + dma-channels = <10>; + interrupts = , + , + , + , + , + , + , + , + , + ; power-domains = <&pd IMX_SC_R_DMA_1_CH0>, - <&pd IMX_SC_R_DMA_1_CH1>, - <&pd IMX_SC_R_DMA_1_CH2>, - <&pd IMX_SC_R_DMA_1_CH3>, - <&pd IMX_SC_R_DMA_1_CH4>, - <&pd IMX_SC_R_DMA_1_CH5>, - <&pd IMX_SC_R_DMA_1_CH6>, - <&pd IMX_SC_R_DMA_1_CH7>; + <&pd IMX_SC_R_DMA_1_CH1>, + <&pd IMX_SC_R_DMA_1_CH2>, + <&pd IMX_SC_R_DMA_1_CH3>, + <&pd IMX_SC_R_DMA_1_CH4>, + <&pd IMX_SC_R_DMA_1_CH5>, + <&pd IMX_SC_R_DMA_1_CH6>, + <&pd IMX_SC_R_DMA_1_CH7>, + <&pd IMX_SC_R_DMA_1_CH8>, + <&pd IMX_SC_R_DMA_1_CH9>; }; &flexcan1 { @@ -112,15 +127,15 @@ }; &flexcan2 { - clocks = <&can1_lpcg 1>, - <&can1_lpcg 0>; + clocks = <&can1_lpcg IMX_LPCG_CLK_4>, + <&can1_lpcg IMX_LPCG_CLK_0>; assigned-clocks = <&clk IMX_SC_R_CAN_1 IMX_SC_PM_CLK_PER>; fsl,clk-source = /bits/ 8 <1>; }; &flexcan3 { - clocks = <&can2_lpcg 1>, - <&can2_lpcg 0>; + clocks = <&can2_lpcg IMX_LPCG_CLK_4>, + <&can2_lpcg IMX_LPCG_CLK_0>; assigned-clocks = <&clk IMX_SC_R_CAN_2 IMX_SC_PM_CLK_PER>; fsl,clk-source = /bits/ 8 <1>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts @@ -175,7 +175,6 @@ vmmc-supply = <®_usdhc2_vmmc>; bus-width = <4>; status = "okay"; - no-sdio; no-mmc; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi @@ -58,7 +58,7 @@ gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; reg = <0x0 0xf1001000 0x0 0x1000>, /* GICD */ - <0x0 0xf1002000 0x0 0x100>; /* GICC */ + <0x0 0xf1002000 0x0 0x2000>; /* GICC */ #address-cells = <0>; #interrupt-cells = <3>; interrupt-controller; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -431,14 +431,14 @@ crypto: crypto@90000 { compatible = "inside-secure,safexcel-eip97ies"; reg = <0x90000 0x20000>; - interrupts = , - , + interrupts = , , , , - ; - interrupt-names = "mem", "ring0", "ring1", - "ring2", "ring3", "eip"; + , + ; + interrupt-names = "ring0", "ring1", "ring2", + "ring3", "eip", "mem"; clocks = <&nb_periph_clk 15>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi @@ -511,14 +511,14 @@ CP11X_LABEL(crypto): crypto@800000 { compatible = "inside-secure,safexcel-eip197b"; reg = <0x800000 0x200000>; - interrupts = <87 IRQ_TYPE_LEVEL_HIGH>, - <88 IRQ_TYPE_LEVEL_HIGH>, + interrupts = <88 IRQ_TYPE_LEVEL_HIGH>, <89 IRQ_TYPE_LEVEL_HIGH>, <90 IRQ_TYPE_LEVEL_HIGH>, <91 IRQ_TYPE_LEVEL_HIGH>, - <92 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "mem", "ring0", "ring1", - "ring2", "ring3", "eip"; + <92 IRQ_TYPE_LEVEL_HIGH>, + <87 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ring0", "ring1", "ring2", "ring3", + "eip", "mem"; clock-names = "core", "reg"; clocks = <&CP11X_LABEL(clk) 1 26>, <&CP11X_LABEL(clk) 1 17>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt2712-evb.dts @@ -129,7 +129,7 @@ }; &pio { - eth_default: eth_default { + eth_default: eth-default-pins { tx_pins { pinmux = , , @@ -156,7 +156,7 @@ }; }; - eth_sleep: eth_sleep { + eth_sleep: eth-sleep-pins { tx_pins { pinmux = , , @@ -182,14 +182,14 @@ }; }; - usb0_id_pins_float: usb0_iddig { + usb0_id_pins_float: usb0-iddig-pins { pins_iddig { pinmux = ; bias-pull-up; }; }; - usb1_id_pins_float: usb1_iddig { + usb1_id_pins_float: usb1-iddig-pins { pins_iddig { pinmux = ; bias-pull-up; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt2712e.dtsi @@ -249,10 +249,11 @@ #clock-cells = <1>; }; - infracfg: syscon@10001000 { + infracfg: clock-controller@10001000 { compatible = "mediatek,mt2712-infracfg", "syscon"; reg = <0 0x10001000 0 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; pericfg: syscon@10003000 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -75,6 +75,7 @@ memory@40000000 { reg = <0 0x40000000 0 0x40000000>; + device_type = "memory"; }; reg_1p8v: regulator-1p8v { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts @@ -57,6 +57,7 @@ memory@40000000 { reg = <0 0x40000000 0 0x20000000>; + device_type = "memory"; }; reg_1p8v: regulator-1p8v { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -252,7 +252,7 @@ clock-names = "hif_sel"; }; - cir: cir@10009000 { + cir: ir-receiver@10009000 { compatible = "mediatek,mt7622-cir"; reg = <0 0x10009000 0 0x1000>; interrupts = ; @@ -283,16 +283,14 @@ }; }; - apmixedsys: apmixedsys@10209000 { - compatible = "mediatek,mt7622-apmixedsys", - "syscon"; + apmixedsys: clock-controller@10209000 { + compatible = "mediatek,mt7622-apmixedsys"; reg = <0 0x10209000 0 0x1000>; #clock-cells = <1>; }; - topckgen: topckgen@10210000 { - compatible = "mediatek,mt7622-topckgen", - "syscon"; + topckgen: clock-controller@10210000 { + compatible = "mediatek,mt7622-topckgen"; reg = <0 0x10210000 0 0x1000>; #clock-cells = <1>; }; @@ -515,7 +513,6 @@ <&pericfg CLK_PERI_AUXADC_PD>; clock-names = "therm", "auxadc"; resets = <&pericfg MT7622_PERI_THERM_SW_RST>; - reset-names = "therm"; mediatek,auxadc = <&auxadc>; mediatek,apmixedsys = <&apmixedsys>; nvmem-cells = <&thermal_calibration>; @@ -734,9 +731,8 @@ power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>; }; - ssusbsys: ssusbsys@1a000000 { - compatible = "mediatek,mt7622-ssusbsys", - "syscon"; + ssusbsys: clock-controller@1a000000 { + compatible = "mediatek,mt7622-ssusbsys"; reg = <0 0x1a000000 0 0x1000>; #clock-cells = <1>; #reset-cells = <1>; @@ -793,9 +789,8 @@ }; }; - pciesys: pciesys@1a100800 { - compatible = "mediatek,mt7622-pciesys", - "syscon"; + pciesys: clock-controller@1a100800 { + compatible = "mediatek,mt7622-pciesys"; reg = <0 0x1a100800 0 0x1000>; #clock-cells = <1>; #reset-cells = <1>; @@ -921,12 +916,13 @@ }; }; - hifsys: syscon@1af00000 { - compatible = "mediatek,mt7622-hifsys", "syscon"; + hifsys: clock-controller@1af00000 { + compatible = "mediatek,mt7622-hifsys"; reg = <0 0x1af00000 0 0x70>; + #clock-cells = <1>; }; - ethsys: syscon@1b000000 { + ethsys: clock-controller@1b000000 { compatible = "mediatek,mt7622-ethsys", "syscon"; reg = <0 0x1b000000 0 0x1000>; @@ -966,9 +962,7 @@ }; eth: ethernet@1b100000 { - compatible = "mediatek,mt7622-eth", - "mediatek,mt2701-eth", - "syscon"; + compatible = "mediatek,mt7622-eth"; reg = <0 0x1b100000 0 0x20000>; interrupts = , , --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts @@ -43,7 +43,7 @@ #cooling-cells = <2>; /* cooling level (0, 1, 2) - pwm inverted */ cooling-levels = <255 96 0>; - pwms = <&pwm 0 10000 0>; + pwms = <&pwm 0 10000>; status = "okay"; }; @@ -146,19 +146,19 @@ &cpu_thermal { cooling-maps { - cpu-active-high { + map-cpu-active-high { /* active: set fan to cooling level 2 */ cooling-device = <&fan 2 2>; trip = <&cpu_trip_active_high>; }; - cpu-active-med { + map-cpu-active-med { /* active: set fan to cooling level 1 */ cooling-device = <&fan 1 1>; trip = <&cpu_trip_active_med>; }; - cpu-active-low { + map-cpu-active-low { /* active: set fan to cooling level 0 */ cooling-device = <&fan 0 0>; trip = <&cpu_trip_active_low>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts @@ -237,12 +237,13 @@ pinctrl-0 = <&spi_flash_pins>; cs-gpios = <0>, <0>; status = "okay"; - spi_nand: spi_nand@0 { + + spi_nand: flash@0 { compatible = "spi-nand"; reg = <0>; spi-max-frequency = <10000000>; - spi-tx-buswidth = <4>; - spi-rx-buswidth = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7986a.dtsi @@ -16,49 +16,49 @@ #address-cells = <2>; #size-cells = <2>; - clk40m: oscillator-40m { - compatible = "fixed-clock"; - clock-frequency = <40000000>; - #clock-cells = <0>; - clock-output-names = "clkxtal"; - }; - cpus { #address-cells = <1>; #size-cells = <0>; cpu0: cpu@0 { - device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x0>; + device_type = "cpu"; + enable-method = "psci"; #cooling-cells = <2>; }; cpu1: cpu@1 { - device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x1>; + device_type = "cpu"; + enable-method = "psci"; #cooling-cells = <2>; }; cpu2: cpu@2 { - device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x2>; + device_type = "cpu"; + enable-method = "psci"; #cooling-cells = <2>; }; cpu3: cpu@3 { - device_type = "cpu"; - enable-method = "psci"; compatible = "arm,cortex-a53"; reg = <0x3>; + device_type = "cpu"; + enable-method = "psci"; #cooling-cells = <2>; }; }; + clk40m: oscillator-40m { + compatible = "fixed-clock"; + clock-frequency = <40000000>; + #clock-cells = <0>; + clock-output-names = "clkxtal"; + }; + psci { compatible = "arm,psci-0.2"; method = "smc"; @@ -121,38 +121,30 @@ }; - timer { - compatible = "arm,armv8-timer"; - interrupt-parent = <&gic>; - interrupts = , - , - , - ; - }; - soc { - #address-cells = <2>; - #size-cells = <2>; compatible = "simple-bus"; ranges; + #address-cells = <2>; + #size-cells = <2>; gic: interrupt-controller@c000000 { compatible = "arm,gic-v3"; - #interrupt-cells = <3>; - interrupt-parent = <&gic>; - interrupt-controller; reg = <0 0x0c000000 0 0x10000>, /* GICD */ <0 0x0c080000 0 0x80000>, /* GICR */ <0 0x0c400000 0 0x2000>, /* GICC */ <0 0x0c410000 0 0x1000>, /* GICH */ <0 0x0c420000 0 0x2000>; /* GICV */ + interrupt-parent = <&gic>; interrupts = ; + interrupt-controller; + #interrupt-cells = <3>; }; infracfg: infracfg@10001000 { compatible = "mediatek,mt7986-infracfg", "syscon"; reg = <0 0x10001000 0 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; wed_pcie: wed-pcie@10003000 { @@ -202,6 +194,19 @@ #interrupt-cells = <2>; }; + pwm: pwm@10048000 { + compatible = "mediatek,mt7986-pwm"; + reg = <0 0x10048000 0 0x1000>; + #pwm-cells = <2>; + interrupts = ; + clocks = <&topckgen CLK_TOP_PWM_SEL>, + <&infracfg CLK_INFRA_PWM_STA>, + <&infracfg CLK_INFRA_PWM1_CK>, + <&infracfg CLK_INFRA_PWM2_CK>; + clock-names = "top", "main", "pwm1", "pwm2"; + status = "disabled"; + }; + sgmiisys0: syscon@10060000 { compatible = "mediatek,mt7986-sgmiisys_0", "syscon"; @@ -234,26 +239,11 @@ ; interrupt-names = "ring0", "ring1", "ring2", "ring3"; clocks = <&infracfg CLK_INFRA_EIP97_CK>; - clock-names = "infra_eip97_ck"; assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>; assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>; status = "disabled"; }; - pwm: pwm@10048000 { - compatible = "mediatek,mt7986-pwm"; - reg = <0 0x10048000 0 0x1000>; - #clock-cells = <1>; - #pwm-cells = <2>; - interrupts = ; - clocks = <&topckgen CLK_TOP_PWM_SEL>, - <&infracfg CLK_INFRA_PWM_STA>, - <&infracfg CLK_INFRA_PWM1_CK>, - <&infracfg CLK_INFRA_PWM2_CK>; - clock-names = "top", "main", "pwm1", "pwm2"; - status = "disabled"; - }; - uart0: serial@11002000 { compatible = "mediatek,mt7986-uart", "mediatek,mt6577-uart"; @@ -311,9 +301,9 @@ spi0: spi@1100a000 { compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm"; + reg = <0 0x1100a000 0 0x100>; #address-cells = <1>; #size-cells = <0>; - reg = <0 0x1100a000 0 0x100>; interrupts = ; clocks = <&topckgen CLK_TOP_MPLL_D2>, <&topckgen CLK_TOP_SPI_SEL>, @@ -325,9 +315,9 @@ spi1: spi@1100b000 { compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm"; + reg = <0 0x1100b000 0 0x100>; #address-cells = <1>; #size-cells = <0>; - reg = <0 0x1100b000 0 0x100>; interrupts = ; clocks = <&topckgen CLK_TOP_MPLL_D2>, <&topckgen CLK_TOP_SPIM_MST_SEL>, @@ -337,6 +327,20 @@ status = "disabled"; }; + thermal: thermal@1100c800 { + compatible = "mediatek,mt7986-thermal"; + reg = <0 0x1100c800 0 0x800>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_THERM_CK>, + <&infracfg CLK_INFRA_ADC_26M_CK>; + clock-names = "therm", "auxadc"; + nvmem-cells = <&thermal_calibration>; + nvmem-cell-names = "calibration-data"; + #thermal-sensor-cells = <1>; + mediatek,auxadc = <&auxadc>; + mediatek,apmixedsys = <&apmixedsys>; + }; + auxadc: adc@1100d000 { compatible = "mediatek,mt7986-auxadc"; reg = <0 0x1100d000 0 0x1000>; @@ -388,39 +392,23 @@ status = "disabled"; }; - thermal: thermal@1100c800 { - #thermal-sensor-cells = <1>; - compatible = "mediatek,mt7986-thermal"; - reg = <0 0x1100c800 0 0x800>; - interrupts = ; - clocks = <&infracfg CLK_INFRA_THERM_CK>, - <&infracfg CLK_INFRA_ADC_26M_CK>, - <&infracfg CLK_INFRA_ADC_FRC_CK>; - clock-names = "therm", "auxadc", "adc_32k"; - mediatek,auxadc = <&auxadc>; - mediatek,apmixedsys = <&apmixedsys>; - nvmem-cells = <&thermal_calibration>; - nvmem-cell-names = "calibration-data"; - }; - pcie: pcie@11280000 { compatible = "mediatek,mt7986-pcie", "mediatek,mt8192-pcie"; + reg = <0x00 0x11280000 0x00 0x4000>; + reg-names = "pcie-mac"; + ranges = <0x82000000 0x00 0x20000000 0x00 + 0x20000000 0x00 0x10000000>; device_type = "pci"; #address-cells = <3>; #size-cells = <2>; - reg = <0x00 0x11280000 0x00 0x4000>; - reg-names = "pcie-mac"; interrupts = ; bus-range = <0x00 0xff>; - ranges = <0x82000000 0x00 0x20000000 0x00 - 0x20000000 0x00 0x10000000>; clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>, <&infracfg CLK_INFRA_IPCIE_CK>, <&infracfg CLK_INFRA_IPCIER_CK>, <&infracfg CLK_INFRA_IPCIEB_CK>; clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m"; - status = "disabled"; phys = <&pcie_port PHY_TYPE_PCIE>; phy-names = "pcie-phy"; @@ -431,6 +419,8 @@ <0 0 0 2 &pcie_intc 1>, <0 0 0 3 &pcie_intc 2>, <0 0 0 4 &pcie_intc 3>; + status = "disabled"; + pcie_intc: interrupt-controller { #address-cells = <0>; #interrupt-cells = <1>; @@ -441,9 +431,9 @@ pcie_phy: t-phy { compatible = "mediatek,mt7986-tphy", "mediatek,generic-tphy-v2"; + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; status = "disabled"; pcie_port: pcie-phy@11c00000 { @@ -468,9 +458,9 @@ usb_phy: t-phy@11e10000 { compatible = "mediatek,mt7986-tphy", "mediatek,generic-tphy-v2"; + ranges = <0 0 0x11e10000 0x1700>; #address-cells = <1>; #size-cells = <1>; - ranges = <0 0 0x11e10000 0x1700>; status = "disabled"; u2port0: usb-phy@0 { @@ -498,8 +488,6 @@ }; ethsys: syscon@15000000 { - #address-cells = <1>; - #size-cells = <1>; compatible = "mediatek,mt7986-ethsys", "syscon"; reg = <0 0x15000000 0 0x1000>; @@ -533,20 +521,6 @@ mediatek,wo-ccif = <&wo_ccif1>; }; - wo_ccif0: syscon@151a5000 { - compatible = "mediatek,mt7986-wo-ccif", "syscon"; - reg = <0 0x151a5000 0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; - }; - - wo_ccif1: syscon@151ad000 { - compatible = "mediatek,mt7986-wo-ccif", "syscon"; - reg = <0 0x151ad000 0 0x1000>; - interrupt-parent = <&gic>; - interrupts = ; - }; - eth: ethernet@15100000 { compatible = "mediatek,mt7986-eth"; reg = <0 0x15100000 0 0x80000>; @@ -579,26 +553,39 @@ <&topckgen CLK_TOP_SGM_325M_SEL>; assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>, <&apmixedsys CLK_APMIXED_SGMPLL>; + #address-cells = <1>; + #size-cells = <0>; mediatek,ethsys = <ðsys>; mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>; mediatek,wed-pcie = <&wed_pcie>; mediatek,wed = <&wed0>, <&wed1>; - #reset-cells = <1>; - #address-cells = <1>; - #size-cells = <0>; status = "disabled"; }; + wo_ccif0: syscon@151a5000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151a5000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + }; + + wo_ccif1: syscon@151ad000 { + compatible = "mediatek,mt7986-wo-ccif", "syscon"; + reg = <0 0x151ad000 0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + }; + wifi: wifi@18000000 { compatible = "mediatek,mt7986-wmac"; + reg = <0 0x18000000 0 0x1000000>, + <0 0x10003000 0 0x1000>, + <0 0x11d10000 0 0x1000>; resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>; reset-names = "consys"; clocks = <&topckgen CLK_TOP_CONN_MCUSYS_SEL>, <&topckgen CLK_TOP_AP2CNN_HOST_SEL>; clock-names = "mcu", "ap2conn"; - reg = <0 0x18000000 0 0x1000000>, - <0 0x10003000 0 0x1000>, - <0 0x11d10000 0 0x1000>; interrupts = , , , @@ -646,4 +633,13 @@ }; }; }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts @@ -152,12 +152,13 @@ pinctrl-0 = <&spi_flash_pins>; cs-gpios = <0>, <0>; status = "okay"; - spi_nand: spi_nand@0 { + + spi_nand: flash@0 { compatible = "spi-nand"; reg = <0>; spi-max-frequency = <10000000>; - spi-tx-buswidth = <4>; - spi-rx-buswidth = <4>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts @@ -82,7 +82,8 @@ }; &mmc1 { - bt_reset: bt-reset { + bluetooth@2 { + reg = <2>; compatible = "mediatek,mt7921s-bluetooth"; pinctrl-names = "default"; pinctrl-0 = <&bt_pins_reset>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi @@ -360,6 +360,10 @@ }; &cros_ec { + cbas { + compatible = "google,cros-cbas"; + }; + keyboard-controller { compatible = "google,cros-ec-keyb-switches"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi @@ -339,6 +339,10 @@ }; &cros_ec { + cbas { + compatible = "google,cros-cbas"; + }; + keyboard-controller { compatible = "google,cros-ec-keyb-switches"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi @@ -343,6 +343,10 @@ }; &cros_ec { + cbas { + compatible = "google,cros-cbas"; + }; + keyboard-controller { compatible = "google,cros-ec-keyb-switches"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi @@ -433,7 +433,6 @@ }; &mt6358_vgpu_reg { - regulator-min-microvolt = <625000>; regulator-max-microvolt = <900000>; regulator-coupled-with = <&mt6358_vsram_gpu_reg>; @@ -937,10 +936,6 @@ google,usb-port-id = <0>; }; - cbas { - compatible = "google,cros-cbas"; - }; - typec { compatible = "google,cros-ec-typec"; #address-cells = <1>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -1628,6 +1628,7 @@ compatible = "mediatek,mt8183-mfgcfg", "syscon"; reg = <0 0x13000000 0 0x1000>; #clock-cells = <1>; + power-domains = <&spm MT8183_POWER_DOMAIN_MFG_ASYNC>; }; gpu: gpu@13040000 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8186.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8186.dtsi @@ -931,11 +931,17 @@ power-domain@MT8186_POWER_DOMAIN_SSUSB { reg = ; + clocks = <&topckgen CLK_TOP_USB_TOP>, + <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>; + clock-names = "sys_ck", "ref_ck"; #power-domain-cells = <0>; }; power-domain@MT8186_POWER_DOMAIN_SSUSB_P1 { reg = ; + clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>, + <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>; + clock-names = "sys_ck", "ref_ck"; #power-domain-cells = <0>; }; @@ -1061,7 +1067,7 @@ reg = ; clocks = <&topckgen CLK_TOP_VENC>, <&vencsys CLK_VENC_CKE1_VENC>; - clock-names = "venc0", "larb"; + clock-names = "venc0", "subsys-larb"; mediatek,infracfg = <&infracfg_ao>; #power-domain-cells = <0>; }; @@ -1530,8 +1536,9 @@ clocks = <&topckgen CLK_TOP_USB_TOP>, <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>, <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_HCLK>, - <&infracfg_ao CLK_INFRA_AO_ICUSB>; - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck"; + <&infracfg_ao CLK_INFRA_AO_ICUSB>, + <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>; + clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; interrupts = ; phys = <&u2port0 PHY_TYPE_USB2>; power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB>; @@ -1595,8 +1602,9 @@ clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>, <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>, <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_HCLK>, - <&clk26m>; - clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck"; + <&clk26m>, + <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>; + clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck"; interrupts = ; phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>; power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB_P1>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi @@ -1336,10 +1336,6 @@ #address-cells = <1>; #size-cells = <0>; - base_detection: cbas { - compatible = "google,cros-cbas"; - }; - cros_ec_pwm: pwm { compatible = "google,cros-ec-pwm"; #pwm-cells = <1>; @@ -1424,7 +1420,7 @@ mt6315_6_vbuck1: vbuck1 { regulator-compatible = "vbuck1"; regulator-name = "Vbcpu"; - regulator-min-microvolt = <300000>; + regulator-min-microvolt = <400000>; regulator-max-microvolt = <1193750>; regulator-enable-ramp-delay = <256>; regulator-allowed-modes = <0 1 2>; @@ -1434,7 +1430,7 @@ mt6315_6_vbuck3: vbuck3 { regulator-compatible = "vbuck3"; regulator-name = "Vlcpu"; - regulator-min-microvolt = <300000>; + regulator-min-microvolt = <400000>; regulator-max-microvolt = <1193750>; regulator-enable-ramp-delay = <256>; regulator-allowed-modes = <0 1 2>; @@ -1451,7 +1447,7 @@ mt6315_7_vbuck1: vbuck1 { regulator-compatible = "vbuck1"; regulator-name = "Vgpu"; - regulator-min-microvolt = <606250>; + regulator-min-microvolt = <400000>; regulator-max-microvolt = <800000>; regulator-enable-ramp-delay = <256>; regulator-allowed-modes = <0 1 2>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -1456,6 +1456,7 @@ reg = <0 0x14001000 0 0x1000>; interrupts = ; clocks = <&mmsys CLK_MM_DISP_MUTEX0>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; mediatek,gce-events = , ; power-domains = <&spm MT8192_POWER_DOMAIN_DISP>; @@ -1814,7 +1815,7 @@ mediatek,scp = <&scp>; power-domains = <&spm MT8192_POWER_DOMAIN_VENC>; clocks = <&vencsys CLK_VENC_SET1_VENC>; - clock-names = "venc-set1"; + clock-names = "venc_sel"; assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>; assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts @@ -23,3 +23,7 @@ &ts_10 { status = "okay"; }; + +&watchdog { + /delete-property/ mediatek,disable-extrst; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts @@ -43,3 +43,7 @@ &ts_10 { status = "okay"; }; + +&watchdog { + /delete-property/ mediatek,disable-extrst; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts @@ -44,3 +44,7 @@ &ts_10 { status = "okay"; }; + +&watchdog { + /delete-property/ mediatek,disable-extrst; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi @@ -264,6 +264,38 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <&mt6359_vcore_buck_reg>; +}; + +&cpu1 { + cpu-supply = <&mt6359_vcore_buck_reg>; +}; + +&cpu2 { + cpu-supply = <&mt6359_vcore_buck_reg>; +}; + +&cpu3 { + cpu-supply = <&mt6359_vcore_buck_reg>; +}; + +&cpu4 { + cpu-supply = <&mt6315_6_vbuck1>; +}; + +&cpu5 { + cpu-supply = <&mt6315_6_vbuck1>; +}; + +&cpu6 { + cpu-supply = <&mt6315_6_vbuck1>; +}; + +&cpu7 { + cpu-supply = <&mt6315_6_vbuck1>; +}; + &dp_intf0 { status = "okay"; @@ -1213,7 +1245,7 @@ mt6315_6_vbuck1: vbuck1 { regulator-compatible = "vbuck1"; regulator-name = "Vbcpu"; - regulator-min-microvolt = <300000>; + regulator-min-microvolt = <400000>; regulator-max-microvolt = <1193750>; regulator-enable-ramp-delay = <256>; regulator-ramp-delay = <6250>; @@ -1231,7 +1263,7 @@ mt6315_7_vbuck1: vbuck1 { regulator-compatible = "vbuck1"; regulator-name = "Vgpu"; - regulator-min-microvolt = <625000>; + regulator-min-microvolt = <400000>; regulator-max-microvolt = <1193750>; regulator-enable-ramp-delay = <256>; regulator-ramp-delay = <6250>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -1998,6 +1998,7 @@ compatible = "mediatek,mt8195-vppsys0", "syscon"; reg = <0 0x14000000 0 0x1000>; #clock-cells = <1>; + mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0 0x1000>; }; dma-controller@14001000 { @@ -2221,6 +2222,7 @@ compatible = "mediatek,mt8195-vppsys1", "syscon"; reg = <0 0x14f00000 0 0x1000>; #clock-cells = <1>; + mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0 0x1000>; }; mutex@14f01000 { @@ -3050,6 +3052,7 @@ reg = <0 0x1c01a000 0 0x1000>; mboxes = <&gce0 0 CMDQ_THR_PRIO_4>; #clock-cells = <1>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000 0x1000>; }; @@ -3231,6 +3234,7 @@ interrupts = ; power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>; clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0x6000 0x1000>; mediatek,gce-events = ; }; @@ -3301,6 +3305,7 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>; clock-names = "vdo1_mutex"; + mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x1000 0x1000>; mediatek,gce-events = ; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts @@ -9,8 +9,8 @@ compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124"; aliases { - rtc0 = "/i2c@7000d000/as3722@40"; - rtc1 = "/rtc@7000e000"; + rtc0 = &as3722; + rtc1 = &tegra_rtc; serial0 = &uarta; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -572,7 +572,7 @@ status = "disabled"; }; - rtc@7000e000 { + tegra_rtc: rtc@7000e000 { compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc"; reg = <0x0 0x7000e000 0x0 0x100>; interrupts = ; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -642,6 +642,7 @@ clocks = <&xo>; clock-names = "ref"; tx-fifo-resize; + snps,parkmode-disable-ss-quirk; snps,is-utmi-l1-suspend; snps,hird-threshold = /bits/ 8 <0x0>; snps,dis_u2_susphy_quirk; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -638,6 +638,7 @@ interrupts = ; phys = <&qusb_phy_0>, <&ssphy_0>; phy-names = "usb2-phy", "usb3-phy"; + snps,parkmode-disable-ss-quirk; snps,is-utmi-l1-suspend; snps,hird-threshold = /bits/ 8 <0x0>; snps,dis_u2_susphy_quirk; @@ -680,6 +681,7 @@ interrupts = ; phys = <&qusb_phy_1>, <&ssphy_1>; phy-names = "usb2-phy", "usb3-phy"; + snps,parkmode-disable-ss-quirk; snps,is-utmi-l1-suspend; snps,hird-threshold = /bits/ 8 <0x0>; snps,dis_u2_susphy_quirk; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -3061,6 +3061,7 @@ snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; snps,is-utmi-l1-suspend; + snps,parkmode-disable-ss-quirk; tx-fifo-resize; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -2146,6 +2146,7 @@ interrupts = ; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; + snps,parkmode-disable-ss-quirk; phys = <&qusb2phy>, <&usb3phy>; phy-names = "usb2-phy", "usb3-phy"; snps,has-lpm-erratum; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/pm4125.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/pm4125.dtsi @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2023, Linaro Ltd + */ + +#include +#include +#include +#include + +&spmi_bus { + pmic@0 { + compatible = "qcom,pm2250", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pon@800 { + compatible = "qcom,pm8916-pon"; + reg = <0x800>; + + pm4125_pwrkey: pwrkey { + compatible = "qcom,pm8941-pwrkey"; + interrupts-extended = <&spmi_bus 0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; + linux,code = ; + debounce = <15625>; + bias-pull-up; + }; + + pm4125_resin: resin { + compatible = "qcom,pm8941-resin"; + interrupts-extended = <&spmi_bus 0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + status = "disabled"; + }; + }; + + rtc@6000 { + compatible = "qcom,pm8941-rtc"; + reg = <0x6000>, <0x6100>; + reg-names = "rtc", "alarm"; + interrupts-extended = <&spmi_bus 0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + }; + + pm4125_gpios: gpio@c000 { + compatible = "qcom,pm2250-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + gpio-ranges = <&pm4125_gpios 0 0 10>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pmic@1 { + compatible = "qcom,pm2250", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm2290.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qcm2290.dtsi @@ -442,6 +442,11 @@ #hwlock-cells = <1>; }; + tcsr_regs: syscon@3c0000 { + compatible = "qcom,qcm2290-tcsr", "syscon"; + reg = <0x0 0x003c0000 0x0 0x40000>; + }; + tlmm: pinctrl@500000 { compatible = "qcom,qcm2290-tlmm"; reg = <0x0 0x00500000 0x0 0x300000>; @@ -690,6 +695,8 @@ #phy-cells = <0>; + qcom,tcsr-reg = <&tcsr_regs 0xb244>; + status = "disabled"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts @@ -82,6 +82,11 @@ no-map; }; + removed_mem: removed@c0000000 { + reg = <0x0 0xc0000000 0x0 0x5100000>; + no-map; + }; + rmtfs_mem: memory@f8500000 { compatible = "qcom,rmtfs-mem"; reg = <0x0 0xf8500000 0x0 0x600000>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -5,6 +5,7 @@ /dts-v1/; +#include #include #include "sc7280.dtsi" #include "pm7325.dtsi" @@ -123,8 +124,8 @@ vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; regulator-name = "vph_pwr"; - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <4350000>; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; }; }; @@ -414,6 +415,33 @@ }; }; }; + +&pm8350c_pwm { + status = "okay"; + + multi-led { + color = ; + function = LED_FUNCTION_STATUS; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = ; + }; + + led@2 { + reg = <2>; + color = ; + }; + + led@3 { + reg = <3>; + color = ; + }; + }; +}; &qupv3_id_0 { status = "okay"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi @@ -62,7 +62,7 @@ vddrf-supply = <&vreg_l1_1p3>; vddch0-supply = <&vdd_ch0_3p3>; - local-bd-address = [ 02 00 00 00 5a ad ]; + local-bd-address = [ 00 00 00 00 00 00 ]; max-speed = <3200000>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -124,8 +124,8 @@ vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; regulator-name = "vph_pwr"; - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <4350000>; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; }; }; @@ -413,6 +413,23 @@ }; }; +&gcc { + protected-clocks = , + , + , + , + , + , + , + , + , + , + , + , + , + ; +}; + &qupv3_id_0 { status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qdu1000.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qdu1000.dtsi @@ -1459,9 +1459,23 @@ system-cache-controller@19200000 { compatible = "qcom,qdu1000-llcc"; - reg = <0 0x19200000 0 0xd80000>, + reg = <0 0x19200000 0 0x80000>, + <0 0x19300000 0 0x80000>, + <0 0x19600000 0 0x80000>, + <0 0x19700000 0 0x80000>, + <0 0x19a00000 0 0x80000>, + <0 0x19b00000 0 0x80000>, + <0 0x19e00000 0 0x80000>, + <0 0x19f00000 0 0x80000>, <0 0x1a200000 0 0x80000>; reg-names = "llcc0_base", + "llcc1_base", + "llcc2_base", + "llcc3_base", + "llcc4_base", + "llcc5_base", + "llcc6_base", + "llcc7_base", "llcc_broadcast_base"; interrupts = ; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts @@ -7,7 +7,7 @@ #include #include "qcm2290.dtsi" -#include "pm2250.dtsi" +#include "pm4125.dtsi" / { model = "Qualcomm Technologies, Inc. Robotics RB1"; @@ -59,6 +59,17 @@ }; }; + i2c2_gpio: i2c { + compatible = "i2c-gpio"; + + sda-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; + scl-gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + leds { compatible = "gpio-leds"; @@ -177,11 +188,29 @@ }; }; +&CPU_PD0 { + /delete-property/ power-domains; +}; + +&CPU_PD1 { + /delete-property/ power-domains; +}; + +&CPU_PD2 { + /delete-property/ power-domains; +}; + +&CPU_PD3 { + /delete-property/ power-domains; +}; + +/delete-node/ &CLUSTER_PD; + &gpi_dma0 { status = "okay"; }; -&i2c2 { +&i2c2_gpio { clock-frequency = <400000>; status = "okay"; @@ -226,7 +255,7 @@ }; &mdss_dsi0 { - vdda-supply = <&pm2250_l5>; + vdda-supply = <&pm4125_l5>; status = "okay"; }; @@ -239,7 +268,7 @@ status = "okay"; }; -&pm2250_resin { +&pm4125_resin { linux,code = ; status = "okay"; }; @@ -263,23 +292,23 @@ compatible = "qcom,rpm-pm2250-regulators"; vdd_s3-supply = <&vph_pwr>; vdd_s4-supply = <&vph_pwr>; - vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm2250_s3>; + vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm4125_s3>; vdd_l4_l17_l18_l19_l20_l21_l22-supply = <&vph_pwr>; - vdd_l13_l14_l15_l16-supply = <&pm2250_s4>; + vdd_l13_l14_l15_l16-supply = <&pm4125_s4>; /* * S1 - VDD_APC * S2 - VDD_CX */ - pm2250_s3: s3 { + pm4125_s3: s3 { /* 0.4V-1.6625V -> 1.3V (Power tree requirements) */ regulator-min-microvolt = <1352000>; regulator-max-microvolt = <1352000>; regulator-boot-on; }; - pm2250_s4: s4 { + pm4125_s4: s4 { /* 1.2V-2.35V -> 2.05V (Power tree requirements) */ regulator-min-microvolt = <2072000>; regulator-max-microvolt = <2072000>; @@ -288,7 +317,7 @@ /* L1 - VDD_MX */ - pm2250_l2: l2 { + pm4125_l2: l2 { /* LPDDR4X VDD2 */ regulator-min-microvolt = <1136000>; regulator-max-microvolt = <1136000>; @@ -296,7 +325,7 @@ regulator-boot-on; }; - pm2250_l3: l3 { + pm4125_l3: l3 { /* LPDDR4X VDDQ */ regulator-min-microvolt = <616000>; regulator-max-microvolt = <616000>; @@ -304,14 +333,14 @@ regulator-boot-on; }; - pm2250_l4: l4 { + pm4125_l4: l4 { /* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2700000>; regulator-allow-set-load; }; - pm2250_l5: l5 { + pm4125_l5: l5 { /* CSI/DSI */ regulator-min-microvolt = <1232000>; regulator-max-microvolt = <1232000>; @@ -319,7 +348,7 @@ regulator-boot-on; }; - pm2250_l6: l6 { + pm4125_l6: l6 { /* DRAM PLL */ regulator-min-microvolt = <928000>; regulator-max-microvolt = <928000>; @@ -327,7 +356,7 @@ regulator-boot-on; }; - pm2250_l7: l7 { + pm4125_l7: l7 { /* Wi-Fi CX/MX */ regulator-min-microvolt = <664000>; regulator-max-microvolt = <664000>; @@ -338,20 +367,20 @@ * L9 - VDD_LPI_MX */ - pm2250_l10: l10 { + pm4125_l10: l10 { /* Wi-Fi RFA */ regulator-min-microvolt = <1304000>; regulator-max-microvolt = <1304000>; }; - pm2250_l11: l11 { + pm4125_l11: l11 { /* GPS RF1 */ regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; regulator-boot-on; }; - pm2250_l12: l12 { + pm4125_l12: l12 { /* USB PHYs */ regulator-min-microvolt = <928000>; regulator-max-microvolt = <928000>; @@ -359,7 +388,7 @@ regulator-boot-on; }; - pm2250_l13: l13 { + pm4125_l13: l13 { /* USB/QFPROM/PLLs */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -367,7 +396,7 @@ regulator-boot-on; }; - pm2250_l14: l14 { + pm4125_l14: l14 { /* SDHCI1 VQMMC */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -376,7 +405,7 @@ regulator-always-on; }; - pm2250_l15: l15 { + pm4125_l15: l15 { /* WCD/DSI/BT VDDIO */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; @@ -385,38 +414,38 @@ regulator-boot-on; }; - pm2250_l16: l16 { + pm4125_l16: l16 { /* GPS RF2 */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; }; - pm2250_l17: l17 { + pm4125_l17: l17 { regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; }; - pm2250_l18: l18 { + pm4125_l18: l18 { /* VDD_PXn */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; - pm2250_l19: l19 { + pm4125_l19: l19 { /* VDD_PXn */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; }; - pm2250_l20: l20 { + pm4125_l20: l20 { /* SDHCI1 VMMC */ regulator-min-microvolt = <2400000>; regulator-max-microvolt = <3600000>; regulator-allow-set-load; }; - pm2250_l21: l21 { + pm4125_l21: l21 { /* SDHCI2 VMMC */ regulator-min-microvolt = <2960000>; regulator-max-microvolt = <3300000>; @@ -424,7 +453,7 @@ regulator-boot-on; }; - pm2250_l22: l22 { + pm4125_l22: l22 { /* Wi-Fi */ regulator-min-microvolt = <3312000>; regulator-max-microvolt = <3312000>; @@ -433,8 +462,8 @@ }; &sdhc_1 { - vmmc-supply = <&pm2250_l20>; - vqmmc-supply = <&pm2250_l14>; + vmmc-supply = <&pm4125_l20>; + vqmmc-supply = <&pm4125_l14>; pinctrl-0 = <&sdc1_state_on>; pinctrl-1 = <&sdc1_state_off>; pinctrl-names = "default", "sleep"; @@ -446,8 +475,8 @@ }; &sdhc_2 { - vmmc-supply = <&pm2250_l21>; - vqmmc-supply = <&pm2250_l4>; + vmmc-supply = <&pm4125_l21>; + vqmmc-supply = <&pm4125_l4>; cd-gpios = <&tlmm 88 GPIO_ACTIVE_LOW>; pinctrl-0 = <&sdc2_state_on &sd_det_in_on>; pinctrl-1 = <&sdc2_state_off &sd_det_in_off>; @@ -518,8 +547,8 @@ }; &usb_qmpphy { - vdda-phy-supply = <&pm2250_l12>; - vdda-pll-supply = <&pm2250_l13>; + vdda-phy-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; status = "okay"; }; @@ -528,17 +557,17 @@ }; &usb_hsphy { - vdd-supply = <&pm2250_l12>; - vdda-pll-supply = <&pm2250_l13>; - vdda-phy-dpdm-supply = <&pm2250_l21>; + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; status = "okay"; }; &wifi { - vdd-0.8-cx-mx-supply = <&pm2250_l7>; - vdd-1.8-xo-supply = <&pm2250_l13>; - vdd-1.3-rfa-supply = <&pm2250_l10>; - vdd-3.3-ch0-supply = <&pm2250_l22>; + vdd-0.8-cx-mx-supply = <&pm4125_l7>; + vdd-1.8-xo-supply = <&pm4125_l13>; + vdd-1.3-rfa-supply = <&pm4125_l10>; + vdd-3.3-ch0-supply = <&pm4125_l22>; qcom,ath10k-calibration-variant = "Thundercomm_RB1"; status = "okay"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts @@ -58,6 +58,17 @@ }; }; + i2c2_gpio: i2c { + compatible = "i2c-gpio"; + + sda-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>; + scl-gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + leds { compatible = "gpio-leds"; @@ -188,7 +199,7 @@ }; }; -&i2c2 { +&i2c2_gpio { clock-frequency = <400000>; status = "okay"; @@ -607,10 +618,6 @@ status = "okay"; }; -&usb_dwc3 { - maximum-speed = "super-speed"; -}; - &usb_hsphy { vdd-supply = <&vreg_l4a_0p9>; vdda-pll-supply = <&vreg_l12a_1p8>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8155p-adp.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sa8155p-adp.dts @@ -367,6 +367,16 @@ }; }; +&pmm8155au_1_gpios { + pmm8155au_1_sdc2_cd: sdc2-cd-default-state { + pins = "gpio4"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; +}; + &qupv3_id_1 { status = "okay"; }; @@ -384,10 +394,10 @@ &sdhc_2 { status = "okay"; - cd-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; + cd-gpios = <&pmm8155au_1_gpios 4 GPIO_ACTIVE_LOW>; pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_on>; - pinctrl-1 = <&sdc2_off>; + pinctrl-0 = <&sdc2_on &pmm8155au_1_sdc2_cd>; + pinctrl-1 = <&sdc2_off &pmm8155au_1_sdc2_cd>; vqmmc-supply = <&vreg_l13c_2p96>; /* IO line power */ vmmc-supply = <&vreg_l17a_2p96>; /* Card power line */ bus-width = <4>; @@ -505,13 +515,6 @@ bias-pull-up; /* pull up */ drive-strength = <16>; /* 16 MA */ }; - - sd-cd-pins { - pins = "gpio96"; - function = "gpio"; - bias-pull-up; /* pull up */ - drive-strength = <2>; /* 2 MA */ - }; }; sdc2_off: sdc2-off-state { @@ -532,13 +535,6 @@ bias-pull-up; /* pull up */ drive-strength = <2>; /* 2 MA */ }; - - sd-cd-pins { - pins = "gpio96"; - function = "gpio"; - bias-pull-up; /* pull up */ - drive-strength = <2>; /* 2 MA */ - }; }; usb2phy_ac_en1_default: usb2phy-ac-en1-default-state { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8540p.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sa8540p.dtsi @@ -168,6 +168,9 @@ }; &gpucc { + /* SA8295P and SA8540P doesn't provide gfx.lvl */ + /delete-property/ power-domains; + status = "disabled"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sa8775p.dtsi @@ -3512,7 +3512,7 @@ interrupts = , , , - ; + ; }; pcie0: pcie@1c00000 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -943,6 +943,8 @@ vddrf-supply = <&pp1300_l2c>; vddch0-supply = <&pp3300_l10c>; max-speed = <3200000>; + + qcom,local-bd-address-broken; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2989,6 +2989,7 @@ iommus = <&apps_smmu 0x540 0>; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; + snps,parkmode-disable-ss-quirk; phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", "usb3-phy"; maximum-speed = "super-speed"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -2178,8 +2178,16 @@ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>; - interrupts = ; - interrupt-names = "msi"; + interrupts = , + , + , + , + , + , + , + ; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>; interrupt-map = <0 0 0 1 &intc 0 0 0 434 IRQ_TYPE_LEVEL_HIGH>, @@ -2345,6 +2353,8 @@ <&apps_smmu 0x4e6 0x0011>; qcom,ee = <0>; qcom,controlled-remotely; + num-channels = <16>; + qcom,num-ees = <4>; }; crypto: crypto@1dfa000 { @@ -3640,7 +3650,7 @@ compatible = "qcom,sc7280-adsp-pas"; reg = <0 0x03700000 0 0x100>; - interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, @@ -3877,7 +3887,7 @@ compatible = "qcom,sc7280-cdsp-pas"; reg = <0 0x0a300000 0 0x10000>; - interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, @@ -4062,6 +4072,7 @@ iommus = <&apps_smmu 0xe0 0x0>; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; + snps,parkmode-disable-ss-quirk; phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", "usb3-phy"; maximum-speed = "super-speed"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8180x.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sc8180x.dtsi @@ -290,7 +290,7 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x40000004>; - entry-latency-us = <241>; + entry-latency-us = <2411>; exit-latency-us = <1461>; min-residency-us = <4488>; local-timer-stop; @@ -298,7 +298,15 @@ }; domain-idle-states { - CLUSTER_SLEEP_0: cluster-sleep-0 { + CLUSTER_SLEEP_APSS_OFF: cluster-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x41000044>; + entry-latency-us = <3300>; + exit-latency-us = <3300>; + min-residency-us = <6000>; + }; + + CLUSTER_SLEEP_AOSS_SLEEP: cluster-sleep-1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x4100a344>; entry-latency-us = <3263>; @@ -582,7 +590,7 @@ CLUSTER_PD: power-domain-cpu-cluster0 { #power-domain-cells = <0>; - domain-idle-states = <&CLUSTER_SLEEP_0>; + domain-idle-states = <&CLUSTER_SLEEP_APSS_OFF &CLUSTER_SLEEP_AOSS_SLEEP>; }; }; @@ -782,6 +790,7 @@ clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; + power-domains = <&rpmhpd SC8180X_CX>; }; qupv3_id_0: geniqup@8c0000 { @@ -2539,11 +2548,14 @@ system-cache-controller@9200000 { compatible = "qcom,sc8180x-llcc"; - reg = <0 0x09200000 0 0x50000>, <0 0x09280000 0 0x50000>, - <0 0x09300000 0 0x50000>, <0 0x09380000 0 0x50000>, - <0 0x09600000 0 0x50000>; + reg = <0 0x09200000 0 0x58000>, <0 0x09280000 0 0x58000>, + <0 0x09300000 0 0x58000>, <0 0x09380000 0 0x58000>, + <0 0x09400000 0 0x58000>, <0 0x09480000 0 0x58000>, + <0 0x09500000 0 0x58000>, <0 0x09580000 0 0x58000>, + <0 0x09600000 0 0x58000>; reg-names = "llcc0_base", "llcc1_base", "llcc2_base", - "llcc3_base", "llcc_broadcast_base"; + "llcc3_base", "llcc4_base", "llcc5_base", + "llcc6_base", "llcc7_base", "llcc_broadcast_base"; interrupts = ; }; @@ -2632,7 +2644,7 @@ resets = <&gcc GCC_USB30_SEC_BCR>; power-domains = <&gcc USB30_SEC_GDSC>; interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 7 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 40 IRQ_TYPE_LEVEL_HIGH>, <&pdc 10 IRQ_TYPE_EDGE_BOTH>, <&pdc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", @@ -2692,9 +2704,15 @@ interrupt-controller; #interrupt-cells = <1>; - interconnects = <&mmss_noc MASTER_MDP_PORT0 0 &mc_virt SLAVE_EBI_CH0 0>, - <&mmss_noc MASTER_MDP_PORT1 0 &mc_virt SLAVE_EBI_CH0 0>; - interconnect-names = "mdp0-mem", "mdp1-mem"; + interconnects = <&mmss_noc MASTER_MDP_PORT0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_MDP_PORT1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "mdp0-mem", + "mdp1-mem", + "cpu-cfg"; iommus = <&apps_smmu 0x800 0x420>; @@ -2723,10 +2741,8 @@ "rot", "lut"; - assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>, - <&dispcc DISP_CC_MDSS_VSYNC_CLK>; - assigned-clock-rates = <460000000>, - <19200000>; + assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + assigned-clock-rates = <19200000>; operating-points-v2 = <&mdp_opp_table>; power-domains = <&rpmhpd SC8180X_MMCX>; @@ -3184,7 +3200,7 @@ <&dispcc DISP_CC_MDSS_AHB_CLK>; clock-names = "aux", "cfg_ahb"; - power-domains = <&dispcc MDSS_GDSC>; + power-domains = <&rpmhpd SC8180X_MX>; #clock-cells = <1>; #phy-cells = <0>; @@ -3210,6 +3226,7 @@ "edp_phy_pll_link_clk", "edp_phy_pll_vco_div_clk"; power-domains = <&rpmhpd SC8180X_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -3248,7 +3265,7 @@ aoss_qmp: power-controller@c300000 { compatible = "qcom,sc8180x-aoss-qmp", "qcom,aoss-qmp"; - reg = <0x0 0x0c300000 0x0 0x100000>; + reg = <0x0 0x0c300000 0x0 0x400>; interrupts = ; mboxes = <&apss_shared 0>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts @@ -416,6 +416,13 @@ regulator-always-on; }; + vreg_l1b: ldo1 { + regulator-name = "vreg_l1b"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = ; + }; + vreg_l3b: ldo3 { regulator-name = "vreg_l3b"; regulator-min-microvolt = <1200000>; @@ -466,6 +473,13 @@ regulator-initial-mode = ; }; + vreg_l8c: ldo8 { + regulator-name = "vreg_l8c"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = ; + }; + vreg_l12c: ldo12 { regulator-name = "vreg_l12c"; regulator-min-microvolt = <1800000>; @@ -499,6 +513,13 @@ vdd-l6-l9-l10-supply = <&vreg_s12b>; vdd-l8-supply = <&vreg_s12b>; + vreg_l2d: ldo2 { + regulator-name = "vreg_l2d"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = ; + }; + vreg_l3d: ldo3 { regulator-name = "vreg_l3d"; regulator-min-microvolt = <1200000>; @@ -527,12 +548,26 @@ regulator-initial-mode = ; }; + vreg_l8d: ldo8 { + regulator-name = "vreg_l8d"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = ; + }; + vreg_l9d: ldo9 { regulator-name = "vreg_l9d"; regulator-min-microvolt = <912000>; regulator-max-microvolt = <912000>; regulator-initial-mode = ; }; + + vreg_l10d: ldo10 { + regulator-name = "vreg_l10d"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = ; + }; }; }; @@ -620,15 +655,16 @@ status = "okay"; - /* FIXME: verify */ touchscreen@10 { - compatible = "hid-over-i2c"; + compatible = "elan,ekth5015m", "elan,ekth6915"; reg = <0x10>; - hid-descr-addr = <0x1>; interrupts-extended = <&tlmm 175 IRQ_TYPE_LEVEL_LOW>; - vdd-supply = <&vreg_misc_3p3>; - vddl-supply = <&vreg_s10b>; + reset-gpios = <&tlmm 99 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + no-reset-on-power-off; + + vcc33-supply = <&vreg_misc_3p3>; + vccio-supply = <&vreg_misc_3p3>; pinctrl-names = "default"; pinctrl-0 = <&ts0_default>; @@ -1203,6 +1239,60 @@ remote-endpoint = <&pmic_glink_con1_hs>; }; +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3 { + dr_mode = "host"; +}; + +&usb_2_hsphy0 { + vdda-pll-supply = <&vreg_l1b>; + vdda18-supply = <&vreg_l1c>; + vdda33-supply = <&vreg_l7d>; + + status = "okay"; +}; + +&usb_2_hsphy1 { + vdda-pll-supply = <&vreg_l8d>; + vdda18-supply = <&vreg_l1c>; + vdda33-supply = <&vreg_l7d>; + + status = "okay"; +}; + +&usb_2_hsphy2 { + vdda-pll-supply = <&vreg_l10d>; + vdda18-supply = <&vreg_l8c>; + vdda33-supply = <&vreg_l2d>; + + status = "okay"; +}; + +&usb_2_hsphy3 { + vdda-pll-supply = <&vreg_l10d>; + vdda18-supply = <&vreg_l8c>; + vdda33-supply = <&vreg_l2d>; + + status = "okay"; +}; + +&usb_2_qmpphy0 { + vdda-phy-supply = <&vreg_l1b>; + vdda-pll-supply = <&vreg_l4d>; + + status = "okay"; +}; + +&usb_2_qmpphy1 { + vdda-phy-supply = <&vreg_l8d>; + vdda-pll-supply = <&vreg_l4d>; + + status = "okay"; +}; + &vamacro { pinctrl-0 = <&dmic01_default>, <&dmic02_default>; pinctrl-names = "default"; @@ -1452,8 +1542,8 @@ reset-n-pins { pins = "gpio99"; function = "gpio"; - output-high; - drive-strength = <16>; + drive-strength = <2>; + bias-disable; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -1774,6 +1774,7 @@ reset-names = "pci"; power-domains = <&gcc PCIE_4_GDSC>; + required-opps = <&rpmhpd_opp_nom>; phys = <&pcie4_phy>; phy-names = "pciephy"; @@ -1798,6 +1799,7 @@ assigned-clock-rates = <100000000>; power-domains = <&gcc PCIE_4_GDSC>; + required-opps = <&rpmhpd_opp_nom>; resets = <&gcc GCC_PCIE_4_PHY_BCR>; reset-names = "phy"; @@ -1872,6 +1874,7 @@ reset-names = "pci"; power-domains = <&gcc PCIE_3B_GDSC>; + required-opps = <&rpmhpd_opp_nom>; phys = <&pcie3b_phy>; phy-names = "pciephy"; @@ -1896,6 +1899,7 @@ assigned-clock-rates = <100000000>; power-domains = <&gcc PCIE_3B_GDSC>; + required-opps = <&rpmhpd_opp_nom>; resets = <&gcc GCC_PCIE_3B_PHY_BCR>; reset-names = "phy"; @@ -1970,6 +1974,7 @@ reset-names = "pci"; power-domains = <&gcc PCIE_3A_GDSC>; + required-opps = <&rpmhpd_opp_nom>; phys = <&pcie3a_phy>; phy-names = "pciephy"; @@ -1995,6 +2000,7 @@ assigned-clock-rates = <100000000>; power-domains = <&gcc PCIE_3A_GDSC>; + required-opps = <&rpmhpd_opp_nom>; resets = <&gcc GCC_PCIE_3A_PHY_BCR>; reset-names = "phy"; @@ -2071,6 +2077,7 @@ reset-names = "pci"; power-domains = <&gcc PCIE_2B_GDSC>; + required-opps = <&rpmhpd_opp_nom>; phys = <&pcie2b_phy>; phy-names = "pciephy"; @@ -2095,6 +2102,7 @@ assigned-clock-rates = <100000000>; power-domains = <&gcc PCIE_2B_GDSC>; + required-opps = <&rpmhpd_opp_nom>; resets = <&gcc GCC_PCIE_2B_PHY_BCR>; reset-names = "phy"; @@ -2169,6 +2177,7 @@ reset-names = "pci"; power-domains = <&gcc PCIE_2A_GDSC>; + required-opps = <&rpmhpd_opp_nom>; phys = <&pcie2a_phy>; phy-names = "pciephy"; @@ -2194,6 +2203,7 @@ assigned-clock-rates = <100000000>; power-domains = <&gcc PCIE_2A_GDSC>; + required-opps = <&rpmhpd_opp_nom>; resets = <&gcc GCC_PCIE_2A_PHY_BCR>; reset-names = "phy"; @@ -2635,7 +2645,7 @@ compatible = "qcom,sc8280xp-adsp-pas"; reg = <0 0x03000000 0 0x100>; - interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, @@ -3331,6 +3341,88 @@ interrupts = ; }; + usb_2: usb@a4f8800 { + compatible = "qcom,sc8280xp-dwc3-mp", "qcom,dwc3"; + reg = <0 0x0a4f8800 0 0x400>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + clocks = <&gcc GCC_CFG_NOC_USB3_MP_AXI_CLK>, + <&gcc GCC_USB30_MP_MASTER_CLK>, + <&gcc GCC_AGGRE_USB3_MP_AXI_CLK>, + <&gcc GCC_USB30_MP_SLEEP_CLK>, + <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>, + <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>, + <&gcc GCC_AGGRE_USB_NOC_NORTH_AXI_CLK>, + <&gcc GCC_AGGRE_USB_NOC_SOUTH_AXI_CLK>, + <&gcc GCC_SYS_NOC_USB_AXI_CLK>; + clock-names = "cfg_noc", "core", "iface", "sleep", "mock_utmi", + "noc_aggr", "noc_aggr_north", "noc_aggr_south", "noc_sys"; + + assigned-clocks = <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_MP_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 857 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 859 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 127 IRQ_TYPE_EDGE_BOTH>, + <&pdc 126 IRQ_TYPE_EDGE_BOTH>, + <&pdc 129 IRQ_TYPE_EDGE_BOTH>, + <&pdc 128 IRQ_TYPE_EDGE_BOTH>, + <&pdc 131 IRQ_TYPE_EDGE_BOTH>, + <&pdc 130 IRQ_TYPE_EDGE_BOTH>, + <&pdc 133 IRQ_TYPE_EDGE_BOTH>, + <&pdc 132 IRQ_TYPE_EDGE_BOTH>, + <&pdc 16 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; + + interrupt-names = "pwr_event_1", "pwr_event_2", + "pwr_event_3", "pwr_event_4", + "hs_phy_1", "hs_phy_2", + "hs_phy_3", "hs_phy_4", + "dp_hs_phy_1", "dm_hs_phy_1", + "dp_hs_phy_2", "dm_hs_phy_2", + "dp_hs_phy_3", "dm_hs_phy_3", + "dp_hs_phy_4", "dm_hs_phy_4", + "ss_phy_1", "ss_phy_2"; + + power-domains = <&gcc USB30_MP_GDSC>; + required-opps = <&rpmhpd_opp_nom>; + + resets = <&gcc GCC_USB30_MP_BCR>; + + interconnects = <&aggre1_noc MASTER_USB3_MP 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_MP 0>; + interconnect-names = "usb-ddr", "apps-usb"; + + wakeup-source; + + status = "disabled"; + + usb_2_dwc3: usb@a400000 { + compatible = "snps,dwc3"; + reg = <0 0x0a400000 0 0xcd00>; + interrupts = ; + iommus = <&apps_smmu 0x800 0x0>; + phys = <&usb_2_hsphy0>, <&usb_2_qmpphy0>, + <&usb_2_hsphy1>, <&usb_2_qmpphy1>, + <&usb_2_hsphy2>, + <&usb_2_hsphy3>; + phy-names = "usb2-0", "usb3-0", + "usb2-1", "usb3-1", + "usb2-2", + "usb2-3"; + dr_mode = "host"; + }; + }; + usb_0: usb@a6f8800 { compatible = "qcom,sc8280xp-dwc3", "qcom,dwc3"; reg = <0 0x0a6f8800 0 0x400>; @@ -4407,7 +4499,7 @@ compatible = "qcom,sc8280xp-nsp0-pas"; reg = <0 0x1b300000 0 0x100>; - interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_nsp0_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_nsp0_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_nsp0_in 2 IRQ_TYPE_EDGE_RISING>, @@ -4538,7 +4630,7 @@ compatible = "qcom,sc8280xp-nsp1-pas"; reg = <0 0x21300000 0 0x100>; - interrupts-extended = <&intc GIC_SPI 887 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 887 IRQ_TYPE_EDGE_RISING>, <&smp2p_nsp1_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_nsp1_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_nsp1_in 2 IRQ_TYPE_EDGE_RISING>, --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -1296,6 +1296,7 @@ interrupts = ; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; + snps,parkmode-disable-ss-quirk; /* * SDM630 technically supports USB3 but I --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -580,7 +580,7 @@ &pcie0 { status = "okay"; perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; - enable-gpio = <&tlmm 134 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 134 GPIO_ACTIVE_HIGH>; vddpe-3v3-supply = <&pcie0_3p3v_dual>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi @@ -508,13 +508,13 @@ }; &q6afedai { - qi2s@22 { - reg = <22>; + dai@22 { + reg = ; qcom,sd-lines = <1>; }; - qi2s@23 { - reg = <23>; + dai@23 { + reg = ; qcom,sd-lines = <0>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -3366,8 +3366,8 @@ qcom,qmp = <&aoss_qmp>; - power-domains = <&rpmhpd SDM845_CX>, - <&rpmhpd SDM845_MX>; + power-domains = <&rpmhpd SDM845_LCX>, + <&rpmhpd SDM845_LMX>; power-domain-names = "lcx", "lmx"; memory-region = <&slpi_mem>; @@ -4080,6 +4080,7 @@ iommus = <&apps_smmu 0x740 0>; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; + snps,parkmode-disable-ss-quirk; phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", "usb3-phy"; }; @@ -4131,6 +4132,7 @@ iommus = <&apps_smmu 0x760 0>; snps,dis_u2_susphy_quirk; snps,dis_enblslpm_quirk; + snps,parkmode-disable-ss-quirk; phys = <&usb_2_hsphy>, <&usb_2_qmpphy>; phy-names = "usb2-phy", "usb3-phy"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6115.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm6115.dtsi @@ -614,6 +614,11 @@ #hwlock-cells = <1>; }; + tcsr_regs: syscon@3c0000 { + compatible = "qcom,sm6115-tcsr", "syscon"; + reg = <0x0 0x003c0000 0x0 0x40000>; + }; + tlmm: pinctrl@500000 { compatible = "qcom,sm6115-tlmm"; reg = <0x0 0x00500000 0x0 0x400000>, @@ -879,6 +884,8 @@ #phy-cells = <0>; + qcom,tcsr-reg = <&tcsr_regs 0xb244>; + status = "disabled"; }; @@ -1061,6 +1068,7 @@ power-domains = <&rpmpd SM6115_VDDCX>; operating-points-v2 = <&sdhc1_opp_table>; + iommus = <&apps_smmu 0x00c0 0x0>; interconnects = <&system_noc MASTER_SDCC_1 RPM_ALWAYS_TAG &bimc SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, <&bimc MASTER_AMPSS_M0 RPM_ALWAYS_TAG @@ -1603,7 +1611,6 @@ interconnect-names = "usb-ddr", "apps-usb"; - qcom,select-utmi-as-pipe-clk; status = "disabled"; usb_dwc3: usb@4e00000 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm6350.dtsi @@ -1249,7 +1249,7 @@ compatible = "qcom,sm6350-adsp-pas"; reg = <0 0x03000000 0 0x100>; - interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, @@ -1509,7 +1509,7 @@ compatible = "qcom,sm6350-cdsp-pas"; reg = <0 0x08300000 0 0x10000>; - interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, @@ -1854,6 +1854,7 @@ snps,dis_enblslpm_quirk; snps,has-lpm-erratum; snps,hird-threshold = /bits/ 8 <0x10>; + snps,parkmode-disable-ss-quirk; phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", "usb3-phy"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6375.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm6375.dtsi @@ -1559,7 +1559,7 @@ compatible = "qcom,sm6375-adsp-pas"; reg = <0 0x0a400000 0 0x100>; - interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -1879,7 +1879,7 @@ phy-names = "pciephy"; perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>; - enable-gpio = <&tlmm 37 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -3025,7 +3025,7 @@ compatible = "qcom,sm8250-slpi-pas"; reg = <0 0x05c00000 0 0x4000>; - interrupts-extended = <&pdc 9 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&pdc 9 IRQ_TYPE_EDGE_RISING>, <&smp2p_slpi_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_slpi_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_slpi_in 2 IRQ_TYPE_EDGE_RISING>, @@ -3729,7 +3729,7 @@ compatible = "qcom,sm8250-cdsp-pas"; reg = <0 0x08300000 0 0x10000>; - interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, @@ -5887,7 +5887,7 @@ compatible = "qcom,sm8250-adsp-pas"; reg = <0 0x17300000 0 0x100>; - interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8450-hdk.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8450-hdk.dts @@ -938,8 +938,8 @@ "TX DMIC3", "MIC BIAS1", "TX SWR_INPUT0", "ADC1_OUTPUT", "TX SWR_INPUT1", "ADC2_OUTPUT", - "TX SWR_INPUT2", "ADC3_OUTPUT", - "TX SWR_INPUT3", "ADC4_OUTPUT"; + "TX SWR_INPUT0", "ADC3_OUTPUT", + "TX SWR_INPUT1", "ADC4_OUTPUT"; wcd-playback-dai-link { link-name = "WCD Playback"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -1028,6 +1028,12 @@ pinctrl-names = "default"; pinctrl-0 = <&qup_uart20_default>; interrupts = ; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; status = "disabled"; }; @@ -1420,6 +1426,12 @@ pinctrl-names = "default"; pinctrl-0 = <&qup_uart7_tx>, <&qup_uart7_rx>; interrupts = ; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; status = "disabled"; }; }; @@ -1765,12 +1777,8 @@ ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>, <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>; - /* - * MSIs for BDF (1:0.0) only works with Device ID 0x5980. - * Hence, the IDs are swapped. - */ - msi-map = <0x0 &gic_its 0x5981 0x1>, - <0x100 &gic_its 0x5980 0x1>; + msi-map = <0x0 &gic_its 0x5980 0x1>, + <0x100 &gic_its 0x5981 0x1>; msi-map-mask = <0xff00>; interrupts = ; interrupt-names = "msi"; @@ -1874,12 +1882,8 @@ ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>; - /* - * MSIs for BDF (1:0.0) only works with Device ID 0x5a00. - * Hence, the IDs are swapped. - */ - msi-map = <0x0 &gic_its 0x5a01 0x1>, - <0x100 &gic_its 0x5a00 0x1>; + msi-map = <0x0 &gic_its 0x5a00 0x1>, + <0x100 &gic_its 0x5a01 0x1>; msi-map-mask = <0xff00>; interrupts = ; interrupt-names = "msi"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8550-mtp.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8550-mtp.dts @@ -874,7 +874,7 @@ wcd_tx: codec@0,3 { compatible = "sdw20217010d00"; reg = <0 3>; - qcom,tx-port-mapping = <1 1 2 3>; + qcom,tx-port-mapping = <2 2 3 4>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8550-qrd.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8550-qrd.dts @@ -978,7 +978,7 @@ wcd_tx: codec@0,3 { compatible = "sdw20217010d00"; reg = <0 3>; - qcom,tx-port-mapping = <1 1 2 3>; + qcom,tx-port-mapping = <2 2 3 4>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -3248,7 +3248,7 @@ spmi_bus: spmi@c400000 { compatible = "qcom,spmi-pmic-arb"; reg = <0 0x0c400000 0 0x3000>, - <0 0x0c500000 0 0x4000000>, + <0 0x0c500000 0 0x400000>, <0 0x0c440000 0 0x80000>, <0 0x0c4c0000 0 0x20000>, <0 0x0c42d000 0 0x4000>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/sm8650.dtsi @@ -2448,10 +2448,12 @@ compatible = "qcom,sm8650-qmp-ufs-phy"; reg = <0 0x01d80000 0 0x2000>; - clocks = <&tcsr TCSR_UFS_CLKREF_EN>, - <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>, + <&tcsr TCSR_UFS_CLKREF_EN>; clock-names = "ref", - "ref_aux"; + "ref_aux", + "qref"; resets = <&ufs_mem_hc 0>; reset-names = "ufsphy"; @@ -3703,7 +3705,7 @@ spmi_bus: spmi@c400000 { compatible = "qcom,spmi-pmic-arb"; reg = <0 0x0c400000 0 0x3000>, - <0 0x0c500000 0 0x4000000>, + <0 0x0c500000 0 0x400000>, <0 0x0c440000 0 0x80000>, <0 0x0c4c0000 0 0x20000>, <0 0x0c42d000 0 0x4000>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-crd.dts @@ -22,6 +22,15 @@ stdout-path = "serial0:115200n8"; }; + reserved-memory { + linux,cma { + compatible = "shared-dma-pool"; + size = <0x0 0x8000000>; + reusable; + linux,cma-default; + }; + }; + vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts @@ -21,6 +21,15 @@ stdout-path = "serial0:115200n8"; }; + reserved-memory { + linux,cma { + compatible = "shared-dma-pool"; + size = <0x0 0x8000000>; + reusable; + linux,cma-default; + }; + }; + vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; @@ -243,7 +252,7 @@ qcom,pmic-id = "e"; vdd-l2-supply = <&vreg_s1f_0p7>; - vdd-l3-supply = <&vph_pwr>; + vdd-l3-supply = <&vreg_s5j_1p2>; vreg_l2e_0p8: ldo2 { regulator-name = "vreg_l2e_0p8"; @@ -349,7 +358,7 @@ qcom,pmic-id = "j"; vdd-l1-supply = <&vreg_s1f_0p7>; - vdd-l2-supply = <&vph_pwr>; + vdd-l2-supply = <&vreg_s5j_1p2>; vdd-l3-supply = <&vreg_s1f_0p7>; vdd-s5-supply = <&vph_pwr>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/qcom/x1e80100.dtsi @@ -278,7 +278,7 @@ domain-idle-states { CLUSTER_CL4: cluster-sleep-0 { - compatible = "arm,idle-state"; + compatible = "domain-idle-state"; idle-state-name = "l2-ret"; arm,psci-suspend-param = <0x01000044>; entry-latency-us = <350>; @@ -287,7 +287,7 @@ }; CLUSTER_CL5: cluster-sleep-1 { - compatible = "arm,idle-state"; + compatible = "domain-idle-state"; idle-state-name = "ret-pll-off"; arm,psci-suspend-param = <0x01000054>; entry-latency-us = <2200>; @@ -3315,7 +3315,6 @@ <0 0x17510000 0 0x10000>, <0 0x17520000 0 0x10000>; reg-names = "drv-0", "drv-1", "drv-2"; - qcom,drv-count = <3>; interrupts = , , --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/r8a779a0.dtsi @@ -658,7 +658,7 @@ avb0: ethernet@e6800000 { compatible = "renesas,etheravb-r8a779a0", "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6800000 0 0x800>; + reg = <0 0xe6800000 0 0x1000>; interrupts = , , , @@ -706,7 +706,7 @@ avb1: ethernet@e6810000 { compatible = "renesas,etheravb-r8a779a0", "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6810000 0 0x800>; + reg = <0 0xe6810000 0 0x1000>; interrupts = , , , --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/r8a779g0.dtsi @@ -161,11 +161,6 @@ }; }; - psci { - compatible = "arm,psci-1.0", "arm,psci-0.2"; - method = "smc"; - }; - extal_clk: extal { compatible = "fixed-clock"; #clock-cells = <0>; @@ -185,13 +180,24 @@ interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; }; - /* External SCIF clock - to be overridden by boards that provide it */ + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + + /* External SCIF clocks - to be overridden by boards that provide them */ scif_clk: scif { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; + scif_clk2: scif2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + soc: soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -681,7 +687,7 @@ interrupts = ; clocks = <&cpg CPG_MOD 516>, <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>, - <&scif_clk>; + <&scif_clk2>; clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x35>, <&dmac0 0x34>, <&dmac1 0x35>, <&dmac1 0x34>; @@ -761,7 +767,7 @@ avb0: ethernet@e6800000 { compatible = "renesas,etheravb-r8a779g0", "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6800000 0 0x800>; + reg = <0 0xe6800000 0 0x1000>; interrupts = , , , @@ -808,7 +814,7 @@ avb1: ethernet@e6810000 { compatible = "renesas,etheravb-r8a779g0", "renesas,etheravb-rcar-gen4"; - reg = <0 0xe6810000 0 0x800>; + reg = <0 0xe6810000 0 0x1000>; interrupts = , , , @@ -1057,7 +1063,7 @@ interrupts = ; clocks = <&cpg CPG_MOD 705>, <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>, - <&scif_clk>; + <&scif_clk2>; clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x59>, <&dmac0 0x58>, <&dmac1 0x59>, <&dmac1 0x58>; @@ -1777,6 +1783,37 @@ }; }; + mmc0: mmc@ee140000 { + compatible = "renesas,sdhi-r8a779g0", + "renesas,rcar-gen4-sdhi"; + reg = <0 0xee140000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 706>, + <&cpg CPG_CORE R8A779G0_CLK_SD0H>; + clock-names = "core", "clkh"; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 706>; + max-frequency = <200000000>; + iommus = <&ipmmu_ds0 32>; + status = "disabled"; + }; + + rpc: spi@ee200000 { + compatible = "renesas,r8a779g0-rpc-if", + "renesas,rcar-gen4-rpc-if"; + reg = <0 0xee200000 0 0x200>, + <0 0x08000000 0 0x04000000>, + <0 0xee208000 0 0x100>; + reg-names = "regs", "dirmap", "wbuf"; + interrupts = ; + clocks = <&cpg CPG_MOD 629>; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 629>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + ipmmu_rt0: iommu@ee480000 { compatible = "renesas,ipmmu-r8a779g0", "renesas,rcar-gen4-ipmmu-vmsa"; @@ -1886,37 +1923,6 @@ #iommu-cells = <1>; }; - mmc0: mmc@ee140000 { - compatible = "renesas,sdhi-r8a779g0", - "renesas,rcar-gen4-sdhi"; - reg = <0 0xee140000 0 0x2000>; - interrupts = ; - clocks = <&cpg CPG_MOD 706>, - <&cpg CPG_CORE R8A779G0_CLK_SD0H>; - clock-names = "core", "clkh"; - power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; - resets = <&cpg 706>; - max-frequency = <200000000>; - iommus = <&ipmmu_ds0 32>; - status = "disabled"; - }; - - rpc: spi@ee200000 { - compatible = "renesas,r8a779g0-rpc-if", - "renesas,rcar-gen4-rpc-if"; - reg = <0 0xee200000 0 0x200>, - <0 0x08000000 0 0x04000000>, - <0 0xee208000 0 0x100>; - reg-names = "regs", "dirmap", "wbuf"; - interrupts = ; - clocks = <&cpg CPG_MOD 629>; - power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; - resets = <&cpg 629>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; - }; - gic: interrupt-controller@f1000000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi @@ -109,7 +109,13 @@ , , , - ; + , + , + , + , + , + , + ; interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3", "irq4", "irq5", "irq6", "irq7", @@ -121,7 +127,9 @@ "tint20", "tint21", "tint22", "tint23", "tint24", "tint25", "tint26", "tint27", "tint28", "tint29", "tint30", "tint31", - "bus-err"; + "bus-err", "ec7tie1-0", "ec7tie2-0", + "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1", + "ec7tiovf-1"; clocks = <&cpg CPG_MOD R9A07G043_IA55_CLK>, <&cpg CPG_MOD R9A07G043_IA55_PCLK>; clock-names = "clk", "pclk"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a07g044.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/r9a07g044.dtsi @@ -905,7 +905,27 @@ , , , - ; + , + , + , + , + , + , + , + ; + interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3", + "irq4", "irq5", "irq6", "irq7", + "tint0", "tint1", "tint2", "tint3", + "tint4", "tint5", "tint6", "tint7", + "tint8", "tint9", "tint10", "tint11", + "tint12", "tint13", "tint14", "tint15", + "tint16", "tint17", "tint18", "tint19", + "tint20", "tint21", "tint22", "tint23", + "tint24", "tint25", "tint26", "tint27", + "tint28", "tint29", "tint30", "tint31", + "bus-err", "ec7tie1-0", "ec7tie2-0", + "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1", + "ec7tiovf-1"; clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>, <&cpg CPG_MOD R9A07G044_IA55_PCLK>; clock-names = "clk", "pclk"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a07g054.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/r9a07g054.dtsi @@ -912,7 +912,27 @@ , , , - ; + , + , + , + , + , + , + , + ; + interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3", + "irq4", "irq5", "irq6", "irq7", + "tint0", "tint1", "tint2", "tint3", + "tint4", "tint5", "tint6", "tint7", + "tint8", "tint9", "tint10", "tint11", + "tint12", "tint13", "tint14", "tint15", + "tint16", "tint17", "tint18", "tint19", + "tint20", "tint21", "tint22", "tint23", + "tint24", "tint25", "tint26", "tint27", + "tint28", "tint29", "tint30", "tint31", + "bus-err", "ec7tie1-0", "ec7tie2-0", + "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1", + "ec7tiovf-1"; clocks = <&cpg CPG_MOD R9A07G054_IA55_CLK>, <&cpg CPG_MOD R9A07G054_IA55_PCLK>; clock-names = "clk", "pclk"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a08g045.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/r9a08g045.dtsi @@ -152,7 +152,10 @@ , , , - ; + , + , + , + ; interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3", "irq4", "irq5", "irq6", "irq7", @@ -164,7 +167,8 @@ "tint20", "tint21", "tint22", "tint23", "tint24", "tint25", "tint26", "tint27", "tint28", "tint29", "tint30", "tint31", - "bus-err"; + "bus-err", "ec7tie1-0", "ec7tie2-0", + "ec7tiovf-0"; clocks = <&cpg CPG_MOD R9A08G045_IA55_CLK>, <&cpg CPG_MOD R9A08G045_IA55_PCLK>; clock-names = "clk", "pclk"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi @@ -193,12 +193,14 @@ #endif &pinctrl { +#if SW_CONFIG3 == SW_ON eth0-phy-irq-hog { gpio-hog; gpios = ; input; line-name = "eth0-phy-irq"; }; +#endif eth0_pins: eth0 { txc { @@ -234,12 +236,14 @@ }; }; +#if SW_CONFIG3 == SW_ON eth1-phy-irq-hog { gpio-hog; gpios = ; input; line-name = "eth1-phy-irq"; }; +#endif eth1_pins: eth1 { txc { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts @@ -5,6 +5,8 @@ */ /dts-v1/; + +#include #include "rk3308.dtsi" / { @@ -24,17 +26,21 @@ leds { compatible = "gpio-leds"; pinctrl-names = "default"; - pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>; + pinctrl-0 = <&green_led>, <&heartbeat_led>; green-led { + color = ; default-state = "on"; + function = LED_FUNCTION_POWER; gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>; label = "rockpis:green:power"; linux,default-trigger = "default-on"; }; blue-led { + color = ; default-state = "on"; + function = LED_FUNCTION_HEARTBEAT; gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; label = "rockpis:blue:user"; linux,default-trigger = "heartbeat"; @@ -126,10 +132,12 @@ }; &emmc { - bus-width = <4>; cap-mmc-highspeed; - mmc-hs200-1_8v; + cap-sd-highspeed; + no-sdio; non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>; vmmc-supply = <&vcc_io>; status = "okay"; }; @@ -214,11 +222,11 @@ pinctrl-0 = <&rtc_32k>; leds { - green_led_gio: green-led-gpio { + green_led: green-led { rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; }; - heartbeat_led_gpio: heartbeat-led-gpio { + heartbeat_led: heartbeat-led { rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts @@ -241,8 +241,8 @@ rk805: pmic@18 { compatible = "rockchip,rk805"; reg = <0x18>; - interrupt-parent = <&gpio2>; - interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&gpio0>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; #clock-cells = <1>; clock-output-names = "xin32k", "rk805-clkout2"; gpio-controller; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -744,11 +744,20 @@ status = "disabled"; ports { - hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; + hdmi_in_vop: endpoint { remote-endpoint = <&vop_out_hdmi>; }; }; + + hdmi_out: port@1 { + reg = <1>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -793,6 +793,7 @@ dma-names = "tx"; pinctrl-names = "default"; pinctrl-0 = <&spdif_tx>; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -804,6 +805,7 @@ clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>; dmas = <&dmac_bus 6>, <&dmac_bus 7>; dma-names = "tx", "rx"; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -817,6 +819,7 @@ dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&i2s_8ch_bus>; + #sound-dai-cells = <0>; status = "disabled"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -450,7 +450,7 @@ dlg,btn-cfg = <50>; dlg,mic-det-thr = <500>; dlg,jack-ins-deb = <20>; - dlg,jack-det-rate = "32ms_64ms"; + dlg,jack-det-rate = "32_64"; dlg,jack-rem-deb = <1>; dlg,a-d-btn-thr = <0xa>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts @@ -779,7 +779,6 @@ }; &pcie0 { - bus-scan-delay-ms = <1000>; ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; num-lanes = <4>; pinctrl-names = "default"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi @@ -416,16 +416,22 @@ gpio1830-supply = <&vcc_1v8>; }; -&pmu_io_domains { - status = "okay"; - pmu1830-supply = <&vcc_1v8>; -}; - -&pwm2 { - status = "okay"; +&pcie_clkreqn_cpm { + rockchip,pins = + <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; }; &pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&q7_thermal_pin>; + + gpios { + q7_thermal_pin: q7-thermal-pin { + rockchip,pins = + <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + i2c8 { i2c8_xfer_a: i2c8-xfer { rockchip,pins = @@ -458,11 +464,20 @@ usb3 { usb3_id: usb3-id { rockchip,pins = - <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; }; }; }; +&pmu_io_domains { + status = "okay"; + pmu1830-supply = <&vcc_1v8>; +}; + +&pwm2 { + status = "okay"; +}; + &sdhci { /* * Signal integrity isn't great at 200MHz but 100MHz has proven stable --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1956,6 +1956,7 @@ hdmi: hdmi@ff940000 { compatible = "rockchip,rk3399-dw-hdmi"; reg = <0x0 0xff940000 0x0 0x20000>; + reg-io-width = <4>; interrupts = ; clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_SFR>, @@ -1964,13 +1965,16 @@ <&cru PLL_VPLL>; clock-names = "iahb", "isfr", "cec", "grf", "ref"; power-domains = <&power RK3399_PD_HDCP>; - reg-io-width = <4>; rockchip,grf = <&grf>; #sound-dai-cells = <0>; status = "disabled"; ports { - hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; #address-cells = <1>; #size-cells = <0>; @@ -1983,6 +1987,10 @@ remote-endpoint = <&vopl_out_hdmi>; }; }; + + hdmi_out: port@1 { + reg = <1>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts @@ -289,7 +289,7 @@ regulator-name = "vdd_gpu"; regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <900000>; + regulator-min-microvolt = <500000>; regulator-max-microvolt = <1350000>; regulator-ramp-delay = <6001>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts @@ -416,6 +416,8 @@ vccio_sd: LDO_REG5 { regulator-name = "vccio_sd"; + regulator-always-on; + regulator-boot-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; @@ -525,9 +527,9 @@ #address-cells = <1>; #size-cells = <0>; - switch@0 { + switch@1f { compatible = "mediatek,mt7531"; - reg = <0>; + reg = <0x1f>; ports { #address-cells = <1>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk356x.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk356x.dtsi @@ -597,6 +597,7 @@ compatible = "rockchip,rk3568-vpu"; reg = <0x0 0xfdea0000 0x0 0x800>; interrupts = ; + interrupt-names = "vdpu"; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; clock-names = "aclk", "hclk"; iommus = <&vdpu_mmu>; @@ -1123,7 +1124,7 @@ dmas = <&dmac1 4>, <&dmac1 5>; dma-names = "tx", "rx"; resets = <&cru SRST_M_I2S2_2CH>; - reset-names = "m"; + reset-names = "tx-m"; rockchip,grf = <&grf>; pinctrl-names = "default"; pinctrl-0 = <&i2s2m0_sclktx --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi @@ -216,9 +216,9 @@ pinctrl-0 = <&i2c7m0_xfer>; status = "okay"; - es8316: audio-codec@11 { + es8316: audio-codec@10 { compatible = "everest,es8316"; - reg = <0x11>; + reg = <0x10>; assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; assigned-clock-rates = <12288000>; clocks = <&cru I2S0_8CH_MCLKOUT>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts @@ -486,6 +486,7 @@ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>; spi-max-frequency = <1000000>; + system-power-controller; vcc1-supply = <&vcc5v0_sys>; vcc2-supply = <&vcc5v0_sys>; @@ -507,7 +508,7 @@ #gpio-cells = <2>; rk806_dvs1_null: dvs1-null-pins { - pins = "gpio_pwrctrl2"; + pins = "gpio_pwrctrl1"; function = "pin_fun0"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts @@ -283,9 +283,9 @@ pinctrl-0 = <&i2c7m0_xfer>; status = "okay"; - es8316: audio-codec@11 { + es8316: audio-codec@10 { compatible = "everest,es8316"; - reg = <0x11>; + reg = <0x10>; assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; assigned-clock-rates = <12288000>; clocks = <&cru I2S0_8CH_MCLKOUT>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts @@ -394,6 +394,7 @@ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, <&rk806_dvs2_null>, <&rk806_dvs3_null>; spi-max-frequency = <1000000>; + system-power-controller; vcc1-supply = <&vcc5v0_sys>; vcc2-supply = <&vcc5v0_sys>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -1704,7 +1704,6 @@ dmas = <&dmac1 0>, <&dmac1 1>; dma-names = "tx", "rx"; power-domains = <&power RK3588_PD_AUDIO>; - rockchip,trcm-sync-tx-only; pinctrl-names = "default"; pinctrl-0 = <&i2s2m1_lrck &i2s2m1_sclk @@ -1725,7 +1724,6 @@ dmas = <&dmac1 2>, <&dmac1 3>; dma-names = "tx", "rx"; power-domains = <&power RK3588_PD_AUDIO>; - rockchip,trcm-sync-tx-only; pinctrl-names = "default"; pinctrl-0 = <&i2s3_lrck &i2s3_sclk --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/Makefile +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/Makefile @@ -57,6 +57,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo # Boards with J7200 SoC k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62-main.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am62-main.dtsi @@ -640,6 +640,8 @@ interrupt-names = "host", "peripheral"; maximum-speed = "high-speed"; dr_mode = "otg"; + snps,usb2-gadget-lpm-disable; + snps,usb2-lpm-disable; }; }; @@ -663,6 +665,8 @@ interrupt-names = "host", "peripheral"; maximum-speed = "high-speed"; dr_mode = "otg"; + snps,usb2-gadget-lpm-disable; + snps,usb2-lpm-disable; }; }; @@ -779,9 +783,10 @@ <0x00 0x30207000 0x00 0x1000>, /* ovr1 */ <0x00 0x30208000 0x00 0x1000>, /* ovr2 */ <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */ - <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */ + <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */ + <0x00 0x30201000 0x00 0x1000>; /* common1 */ reg-names = "common", "vidl1", "vid", - "ovr1", "ovr2", "vp1", "vp2"; + "ovr1", "ovr2", "vp1", "vp2", "common1"; power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 186 6>, <&dss_vp1_clk>, --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi @@ -60,7 +60,7 @@ memory@80000000 { device_type = "memory"; - reg = <0x00000000 0x80000000 0x00000000 0x40000000>; /* 1G RAM */ + reg = <0x00000000 0x80000000 0x00000000 0x80000000>; /* 2G RAM */ }; opp-table { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi @@ -187,6 +187,8 @@ ranges = <0x79000000 0x00 0x79000000 0x8000>, <0x79020000 0x00 0x79020000 0x8000>; power-domains = <&k3_pds 7 TI_SCI_PD_EXCLUSIVE>; + status = "disabled"; + mcu_r5fss0_core0: r5f@79000000 { compatible = "ti,am62-r5f"; reg = <0x79000000 0x00008000>, --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi @@ -78,6 +78,7 @@ ranges = <0x78000000 0x00 0x78000000 0x8000>, <0x78100000 0x00 0x78100000 0x8000>; power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>; + status = "disabled"; wkup_r5fss0_core0: r5f@78000000 { compatible = "ti,am62-r5f"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am62p.dtsi @@ -71,7 +71,7 @@ <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */ <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */ <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */ - <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>, /* DMSS */ + <0x00 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */ <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */ <0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */ <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */ --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts @@ -445,6 +445,10 @@ }; &cpsw3g_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&main_mdio1_pins_default>; + status = "okay"; + cpsw3g_phy0: ethernet-phy@0 { reg = <0>; ti,rx-internal-delay = ; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am64-main.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am64-main.dtsi @@ -633,6 +633,9 @@ ti,otap-del-sel-mmc-hs = <0x0>; ti,otap-del-sel-ddr52 = <0x6>; ti,otap-del-sel-hs200 = <0x7>; + ti,itap-del-sel-legacy = <0x10>; + ti,itap-del-sel-mmc-hs = <0xa>; + ti,itap-del-sel-ddr52 = <0x3>; status = "disabled"; }; @@ -645,12 +648,16 @@ clock-names = "clk_ahb", "clk_xin"; ti,trm-icp = <0x2>; ti,otap-del-sel-legacy = <0x0>; - ti,otap-del-sel-sd-hs = <0xf>; + ti,otap-del-sel-sd-hs = <0x0>; ti,otap-del-sel-sdr12 = <0xf>; ti,otap-del-sel-sdr25 = <0xf>; ti,otap-del-sel-sdr50 = <0xc>; ti,otap-del-sel-sdr104 = <0x6>; ti,otap-del-sel-ddr50 = <0x9>; + ti,itap-del-sel-legacy = <0x0>; + ti,itap-del-sel-sd-hs = <0x0>; + ti,itap-del-sel-sdr12 = <0x0>; + ti,itap-del-sel-sdr25 = <0x0>; ti,clkbuf-sel = <0x7>; status = "disabled"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -1019,9 +1019,10 @@ <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */ <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */ <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */ - <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */ + <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */ + <0x0 0x04a01000 0x0 0x1000>; /* common1 */ reg-names = "common", "vidl1", "vid", - "ovr1", "ovr2", "vp1", "vp2"; + "ovr1", "ovr2", "vp1", "vp2", "common1"; ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am69-sk.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-am69-sk.dts @@ -646,7 +646,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pmic_irq_pins_default>; interrupt-parent = <&wkup_gpio0>; - interrupts = <39 IRQ_TYPE_EDGE_FALLING>; + interrupts = <83 IRQ_TYPE_EDGE_FALLING>; gpio-controller; #gpio-cells = <2>; ti,primary-pmic; @@ -918,13 +918,9 @@ pinctrl-names = "default"; pinctrl-0 = <&dss_vout0_pins_default>; assigned-clocks = <&k3_clks 218 2>, - <&k3_clks 218 5>, - <&k3_clks 218 14>, - <&k3_clks 218 18>; + <&k3_clks 218 5>; assigned-clock-parents = <&k3_clks 218 3>, - <&k3_clks 218 7>, - <&k3_clks 218 16>, - <&k3_clks 218 22>; + <&k3_clks 218 7>; }; &serdes_wiz4 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -91,24 +91,25 @@ }; &wkup_pmx0 { +}; + +&wkup_pmx2 { mcu_uart0_pins_default: mcu-uart0-default-pins { pinctrl-single,pins = < - J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */ - J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */ - J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */ - J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */ + J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */ + J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */ + J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */ + J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */ >; }; wkup_uart0_pins_default: wkup-uart0-default-pins { pinctrl-single,pins = < - J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */ - J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */ + J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */ + J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */ >; }; -}; -&wkup_pmx2 { mcu_cpsw_pins_default: mcu-cpsw-default-pins { pinctrl-single,pins = < J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */ @@ -210,7 +211,6 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mcu_uart0_pins_default>; - clock-frequency = <96000000>; }; &main_uart0 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi @@ -353,9 +353,9 @@ hbmc_mux: mux-controller@47000004 { compatible = "reg-mux"; - reg = <0x00 0x47000004 0x00 0x2>; + reg = <0x00 0x47000004 0x00 0x4>; #mux-control-cells = <1>; - mux-reg-masks = <0x4 0x2>; /* HBMC select */ + mux-reg-masks = <0x0 0x2>; /* HBMC select */ }; hbmc: hyperbus@47034000 { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j721e-sk.dts @@ -574,7 +574,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pmic_irq_pins_default>; interrupt-parent = <&wkup_gpio0>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; gpio-controller; #gpio-cells = <2>; ti,primary-pmic; @@ -651,7 +651,7 @@ reg = <0x4c>; system-power-controller; interrupt-parent = <&wkup_gpio0>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; gpio-controller; #gpio-cells = <2>; buck1234-supply = <&vsys_3v3>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts @@ -190,8 +190,6 @@ &wkup_pmx2 { wkup_uart0_pins_default: wkup-uart0-default-pins { pinctrl-single,pins = < - J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */ - J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */ J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */ J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */ >; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi @@ -663,7 +663,7 @@ compatible = "ti,j7200-vtm"; reg = <0x00 0x42040000 0x0 0x350>, <0x00 0x42050000 0x0 0x350>; - power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>; + power-domains = <&k3_pds 180 TI_SCI_PD_SHARED>; #thermal-sensor-cells = <1>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts @@ -335,8 +335,6 @@ wkup_uart0_pins_default: wkup-uart0-default-pins { bootph-all; pinctrl-single,pins = < - J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */ - J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */ J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */ J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */ >; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi @@ -52,12 +52,12 @@ compatible = "reg-mux"; reg = <0x00004080 0x30>; #mux-control-cells = <1>; - mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */ - <0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */ - <0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */ - <0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */ - <0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */ - <0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */ + mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */ + <0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */ + <0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */ + <0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */ + <0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */ + <0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */ idle-states = , , , --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi @@ -628,7 +628,7 @@ compatible = "ti,j7200-vtm"; reg = <0x00 0x42040000 0x00 0x350>, <0x00 0x42050000 0x00 0x350>; - power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>; + power-domains = <&k3_pds 243 TI_SCI_PD_SHARED>; #thermal-sensor-cells = <1>; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/Makefile +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/Makefile @@ -17,9 +17,66 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu106-revA.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu111-revA.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu1275-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu1275-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu1285-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-a2197-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-dlc21-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-e-a2197-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-e-a2197-00-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-g-a2197-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-m-a2197-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-m-a2197-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-m-a2197-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-01-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-02-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-03-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-04-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-05-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-revC.dtb + +zynqmp-p-a2197-00-revA-x-prc-01-revA-dtbs := zynqmp-p-a2197-00-revA.dtb zynqmp-p-a2197-00-revA-x-prc-01-revA.dtbo +zynqmp-p-a2197-00-revA-x-prc-02-revA-dtbs := zynqmp-p-a2197-00-revA.dtb zynqmp-p-a2197-00-revA-x-prc-02-revA.dtbo +zynqmp-p-a2197-00-revA-x-prc-03-revA-dtbs := zynqmp-p-a2197-00-revA.dtb zynqmp-p-a2197-00-revA-x-prc-03-revA.dtbo +zynqmp-p-a2197-00-revA-x-prc-04-revA-dtbs := zynqmp-p-a2197-00-revA.dtb zynqmp-p-a2197-00-revA-x-prc-04-revA.dtbo +zynqmp-p-a2197-00-revA-x-prc-05-revA-dtbs := zynqmp-p-a2197-00-revA.dtb zynqmp-p-a2197-00-revA-x-prc-05-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-04-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-p-a2197-00-revA-x-prc-05-revA.dtb + +zynqmp-sc-vek280-revA-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vek280-revA.dtbo +zynqmp-sc-vek280-revB-dtbs := zynqmp-sc-revC.dtb zynqmp-sc-vek280-revB.dtbo +zynqmp-sc-vhk158-revA-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vhk158-revA.dtbo +zynqmp-sc-vpk120-revB-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vpk120-revB.dtbo +zynqmp-sc-vpk180-revA-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vpk180-revA.dtbo +zynqmp-sc-vpk180-revB-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vpk180-revB.dtbo +zynqmp-sc-vn-p-b2197-00-revA-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vn-p-b2197-00-revA.dtbo +zynqmp-sc-vm-p-m1369-00-revA-dtbs := zynqmp-sc-revB.dtb zynqmp-sc-vm-p-m1369-00-revA.dtbo + +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vek280-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vek280-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vhk158-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vpk120-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vpk180-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vpk180-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vn-p-b2197-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sc-vm-p-m1369-00-revA.dtb + +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-vp-x-a2785-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-vpk120-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu208-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu216-revA.dtb + +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu670-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu670-revB.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k24-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k24-revA.dtb zynqmp-sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revA.dtb @@ -29,3 +86,88 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revA.dtb zynqmp-smk-k26-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revB.dtb +zynqmp-sm-k26-revA-sck-kr-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo +zynqmp-smk-k26-revA-sck-kr-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo +zynqmp-smk-k26-revA-sck-kr-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo + +zynqmp-sm-k24-revA-sck-kd-g-revA-dtbs := zynqmp-sm-k24-revA.dtb zynqmp-sck-kd-g-revA.dtbo +zynqmp-smk-k24-revA-sck-kd-g-revA-dtbs := zynqmp-smk-k24-revA.dtb zynqmp-sck-kd-g-revA.dtbo +zynqmp-sm-k24-revA-sck-kv-g-revB-dtbs := zynqmp-sm-k24-revA.dtb zynqmp-sck-kv-g-revB.dtbo +zynqmp-smk-k24-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k24-revA.dtb zynqmp-sck-kv-g-revB.dtbo +zynqmp-sm-k26-revA-sck-kr-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo + +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kr-g-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kr-g-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kr-g-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kr-g-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k24-revA-sck-kd-g-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k24-revA-sck-kd-g-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k24-revA-sck-kv-g-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k24-revA-sck-kv-g-revB.dtb + +# Versal boards +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-emb-plus-ve2302-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-v350-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vek280-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vek280-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-01-revA-ospi.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-04-revA-ospi.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-04-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA-x-prc-05-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vc-p-a2197-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-rev1.1-x-ebm-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-rev1.1-x-ebm-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-rev1.1-x-ebm-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-rev1.1.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revA-x-ebm-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revA-x-ebm-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revA-x-ebm-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck5000-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-rev1.1-x-ebm-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-rev1.1-x-ebm-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-rev1.1-x-ebm-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-rev1.1.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-revA-x-ebm-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-revA-x-ebm-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-revA-x-ebm-03-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vmk180-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vp-x-a2785-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vhk158-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vpk120-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vpk120-revB.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vpk180-revA.dtb + +versal-vck190-revB-x-ebm-01-revA-dtbs := versal-vck190-revA.dtb versal-x-ebm-01-revA.dtbo +versal-vck190-revB-x-ebm-02-revA-dtbs := versal-vck190-revA.dtb versal-x-ebm-02-revA.dtbo +versal-vck190-revB-x-ebm-03-revA-dtbs := versal-vck190-revA.dtb versal-x-ebm-03-revA.dtbo + +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revB-x-ebm-01-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revB-x-ebm-02-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-vck190-revB-x-ebm-03-revA.dtb + +# Versal NET platforms +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-p-b2197-00-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-x-b2197-01-revA.dtb + +versal-net-vn-p-b2197-00-revA-x-prc-07-revA-dtbs := versal-net-vn-p-b2197-00-revA.dtb x-prc-07-revA.dtbo +versal-net-vn-p-b2197-00-revA-x-prc-07-i3c-revA-dtbs := versal-net-vn-p-b2197-00-revA.dtb x-prc-07-i3c-revA.dtbo +versal-net-vn-p-b2197-00-revA-x-prc-08-revA-dtbs := versal-net-vn-p-b2197-00-revA.dtb x-prc-08-revA.dtbo +versal-net-vn-p-b2197-00-revA-x-prc-09-revA-dtbs := versal-net-vn-p-b2197-00-revA.dtb x-prc-09-revA.dtbo +versal-net-vn-p-b2197-00-revA-x-prc-09-i3c-revA-dtbs := versal-net-vn-p-b2197-00-revA.dtb x-prc-09-i3c-revA.dtbo + +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-p-b2197-00-revA-x-prc-07-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-p-b2197-00-revA-x-prc-07-i3c-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-p-b2197-00-revA-x-prc-08-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-p-b2197-00-revA-x-prc-09-revA.dtb +dtb-$(CONFIG_ARCH_ZYNQMP) += versal-net-vn-p-b2197-00-revA-x-prc-09-i3c-revA.dtb + +# Make sure that symbols are compiled in for device trees that are not overlayed +DTC_FLAGS += -@ --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-clk.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-clk.dtsi @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal with PM + * + * (C) Copyright 2017 - 2022, Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include + +/ { + pl_alt_ref_clk: pl_alt_ref_clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; + }; + + ref_clk: ref_clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; + }; + + can0_clk: can0_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&versal_clk CAN0_REF>; + clock-div = <2>; + clock-mult = <1>; + }; + + can1_clk: can1_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&versal_clk CAN1_REF>; + clock-div = <2>; + clock-mult = <1>; + }; + + firmware { + versal_firmware: versal-firmware { + compatible = "xlnx,versal-firmware"; + interrupt-parent = <&gic>; + bootph-all; + method = "smc"; + #power-domain-cells = <1>; + + versal_clk: clock-controller { + bootph-all; + #clock-cells = <1>; + compatible = "xlnx,versal-clk"; + clocks = <&ref_clk>, <&pl_alt_ref_clk>; + clock-names = "ref_clk", "pl_alt_ref_clk"; + }; + + zynqmp_power: zynqmp-power { + compatible = "xlnx,zynqmp-power"; + }; + + versal_reset: reset-controller { + compatible = "xlnx,versal-reset"; + #reset-cells = <1>; + }; + + pinctrl0: pinctrl { + compatible = "xlnx,versal-pinctrl"; + }; + + versal_sec_cfg: versal-sec-cfg { + compatible = "xlnx,versal-sec-cfg"; + #address-cells = <1>; + #size-cells = <1>; + + bbram_zeroize: bbram-zeroize@4 { + reg = <0x04 0x4>; + }; + + bbram_key: bbram-key@10 { + reg = <0x10 0x20>; + }; + + bbram_usr: bbram-usr@30 { + reg = <0x30 0x4>; + }; + + bbram_lock: bbram-lock@48 { + reg = <0x48 0x4>; + }; + + user_key0: user-key@110 { + reg = <0x110 0x20>; + }; + + user_key1: user-key@130 { + reg = <0x130 0x20>; + }; + + user_key2: user-key@150 { + reg = <0x150 0x20>; + }; + + user_key3: user-key@170 { + reg = <0x170 0x20>; + }; + + user_key4: user-key@190 { + reg = <0x190 0x20>; + }; + + user_key5: user-key@1b0 { + reg = <0x1b0 0x20>; + }; + + user_key6: user-key@1d0 { + reg = <0x1d0 0x20>; + }; + + user_key7: user-key@1f0 { + reg = <0x1f0 0x20>; + }; + }; + }; + }; +}; + +&cpu0 { + clocks = <&versal_clk ACPU>; +}; + +&can0 { + clocks = <&can0_clk>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_CAN_FD_0>; +}; + +&can1 { + clocks = <&can1_clk>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_CAN_FD_1>; +}; + +&gem0 { + clocks = <&versal_clk LPD_LSBUS>, + <&versal_clk GEM0_REF>, <&versal_clk GEM0_TX>, + <&versal_clk GEM0_RX>, <&versal_clk GEM_TSU>; + power-domains = <&versal_firmware PM_DEV_GEM_0>; +}; + +&gem1 { + clocks = <&versal_clk LPD_LSBUS>, + <&versal_clk GEM1_REF>, <&versal_clk GEM1_TX>, + <&versal_clk GEM1_RX>, <&versal_clk GEM_TSU>; + power-domains = <&versal_firmware PM_DEV_GEM_1>; +}; + +&gpio0 { + clocks = <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_GPIO>; +}; + +&gpio1 { + clocks = <&versal_clk PMC_LSBUS_REF>; + power-domains = <&versal_firmware PM_DEV_GPIO_PMC>; +}; + +&i2c0 { + clocks = <&versal_clk I2C0_REF>; + power-domains = <&versal_firmware PM_DEV_I2C_0>; +}; + +&i2c1 { + clocks = <&versal_clk I2C1_REF>; + power-domains = <&versal_firmware PM_DEV_I2C_1>; +}; + +&i2c2 { + clocks = <&versal_clk I2C_REF>; + power-domains = <&versal_firmware PM_DEV_I2C_PMC>; +}; + +&lpd_dma_chan0 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_0>; +}; + +&lpd_dma_chan1 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_1>; +}; + +&lpd_dma_chan2 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_2>; +}; + +&lpd_dma_chan3 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_3>; +}; + +&lpd_dma_chan4 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_4>; +}; + +&lpd_dma_chan5 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_5>; +}; + +&lpd_dma_chan6 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_6>; +}; + +&lpd_dma_chan7 { + clocks = <&versal_clk ADMA>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_ADMA_7>; +}; + +&qspi { + clocks = <&versal_clk QSPI_REF>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_QSPI>; +}; + +&ospi { + clocks = <&versal_clk OSPI_REF>; + power-domains = <&versal_firmware PM_DEV_OSPI>; + reset-names = "qspi"; + resets = <&versal_reset VERSAL_RST_OSPI>; +}; + +&rtc { + power-domains = <&versal_firmware PM_DEV_RTC>; +}; + +&serial0 { + clocks = <&versal_clk UART0_REF>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_UART_0>; +}; + +&serial1 { + clocks = <&versal_clk UART1_REF>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_UART_1>; +}; + +&sdhci0 { + clocks = <&versal_clk SDIO0_REF>, <&versal_clk LPD_LSBUS>, + <&versal_clk SD_DLL_REF>; + power-domains = <&versal_firmware PM_DEV_SDIO_0>; +}; + +&sdhci1 { + clocks = <&versal_clk SDIO1_REF>, <&versal_clk LPD_LSBUS>, + <&versal_clk SD_DLL_REF>; + power-domains = <&versal_firmware PM_DEV_SDIO_1>; +}; + +&spi0 { + clocks = <&versal_clk SPI0_REF>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_SPI_0>; +}; + +&spi1 { + clocks = <&versal_clk SPI1_REF>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_SPI_1>; +}; + +&ttc0 { + clocks = <&versal_clk TTC0>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_TTC_0>; +}; + +&ttc1 { + clocks = <&versal_clk TTC1>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_TTC_1>; +}; + +&ttc2 { + clocks = <&versal_clk TTC2>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_TTC_2>; +}; + +&ttc3 { + clocks = <&versal_clk TTC3>, <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_TTC_3>; +}; + +&usb0 { + clocks = <&versal_clk USB0_BUS_REF>, <&versal_clk USB3_DUAL_REF>; + power-domains = <&versal_firmware PM_DEV_USB_0>; + resets = <&versal_reset VERSAL_RST_USB_0>; +}; + +&dwc3_0 { + clocks = <&versal_clk USB0_BUS_REF>; +}; + +&watchdog { + clocks = <&versal_clk FPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_SWDT_FPD>; +}; + +&watchdog1 { + clocks = <&versal_clk LPD_LSBUS>; + power-domains = <&versal_firmware PM_DEV_SWDT_LPD>; +}; + +&sysmon0 { + xlnx,nodeid = ; +}; + +&sysmon1 { + xlnx,nodeid = ; +}; + +&sysmon2 { + xlnx,nodeid = ; +}; + +&sysmon3 { + xlnx,nodeid = ; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-emb-plus-ve2302-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-emb-plus-ve2302-revA.dts @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal Embedded+ VE2302 revA + * + * (C) Copyright 2023 - 2024, Advanced Micro Devices, Inc + * + * Michal Simek + */ + +#include +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + compatible = "xlnx,versal-emb-plus-ve2302-revA", + "xlnx,versal-emb-plus-ve2302", + "xlnx,versal"; + model = "Xilinx Versal Embedded+ VE2302 revA"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x1 0x80000000>; /* 8GB */ + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + i2c0 = &i2c0; + }; + + /* For extension board */ + onewire { + compatible = "w1-gpio"; + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + }; +}; + +&serial1 { /* PMC_MIO20/21 */ + status = "okay"; +}; + +&i2c0 { /* PS_MIO 10/11 - to Ryzen */ + status = "okay"; +}; + +&gpio0 { + status = "okay"; + gpio-line-names = "GPIO_LED2", "GPIO_LED3", "GPIO_LED4", "", "1WIRE", /* 0 - 4 */ + "", "FUSA", "", "EGPIO", "AGPIO", /* 5 - 9 */ + "I2C0_SCL", "I2C0_SDA", "", "", "", /* 10 - 14 */ + "", "", "", "", "", /* 15 - 19 */ + "", "", "", "", "3V3_MON_N", /* 20 - 24 */ + "3V3_MON_P", /* 25, MIO end and EMIO start */ + "", "", "", /* 26 - 29 */ + "", "", "", "", "", /* 30 - 34 */ + "", "", "", "", "", /* 35 - 39 */ + "", "", "", "", "", /* 40 - 44 */ + "", "", "", "", "", /* 45 - 49 */ + "", "", "", "", "", /* 50 - 54 */ + "", "", ""; /* 55 - 57 */ +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-net-clk-ccf.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-net-clk-ccf.dtsi @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal with PM + * + * Copyright (C) 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include + +/ { + ref_clk: ref_clk { + bootph-all; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; + }; + + can0_clk: can0-clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&versal_net_clk CAN0_REF_2X>; + clock-div = <2>; + clock-mult = <1>; + }; + + can1_clk: can1-clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&versal_net_clk CAN1_REF_2X>; + clock-div = <2>; + clock-mult = <1>; + }; + + firmware { + versal_net_firmware: versal-net-firmware { + compatible = "xlnx,versal-net-firmware", "xlnx,versal-firmware"; + bootph-all; + method = "smc"; + #power-domain-cells = <1>; + + versal_net_reset: reset-controller { + compatible = "xlnx,versal-net-reset"; + #reset-cells = <1>; + }; + + versal_net_clk: clock-controller { + bootph-all; + #clock-cells = <1>; + compatible = "xlnx,versal-net-clk", "xlnx,versal-clk"; + clocks = <&ref_clk>, <&ref_clk>; + clock-names = "ref_clk", "pl_alt_ref_clk"; + }; + + versal_net_power: zynqmp-power { /* untested */ + compatible = "xlnx,zynqmp-power"; + interrupt-parent = <&gic>; + interrupts = <0 57 4>; + mboxes = <&ipi_mailbox_pmu1 0>, + <&ipi_mailbox_pmu1 1>; + mbox-names = "tx", "rx"; + }; + + versal_sec_cfg: versal-sec-cfg { /* untested */ + compatible = "xlnx,versal-sec-cfg"; + #address-cells = <1>; + #size-cells = <1>; + + bbram_zeroize: bbram-zeroize@4 { + reg = <0x04 0x4>; + }; + + bbram_key: bbram-key@10 { + reg = <0x10 0x20>; + }; + + bbram_usr: bbram-usr@30 { + reg = <0x30 0x4>; + }; + + bbram_lock: bbram-lock@48 { + reg = <0x48 0x4>; + }; + + user_key0: user-key@110 { + reg = <0x110 0x20>; + }; + + user_key1: user-key@130 { + reg = <0x130 0x20>; + }; + + user_key2: user-key@150 { + reg = <0x150 0x20>; + }; + + user_key3: user-key@170 { + reg = <0x170 0x20>; + }; + + user_key4: user-key@190 { + reg = <0x190 0x20>; + }; + + user_key5: user-key@1b0 { + reg = <0x1b0 0x20>; + }; + + user_key6: user-key@1d0 { + reg = <0x1d0 0x20>; + }; + + user_key7: user-key@1f0 { + reg = <0x1f0 0x20>; + }; + }; + }; + }; + + zynqmp-ipi { + compatible = "xlnx,zynqmp-ipi-mailbox"; + interrupt-parent = <&gic>; + interrupts = <0 57 4>; + xlnx,ipi-id = <2>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + ipi_mailbox_pmu1: mailbox@eb3f0440 { + reg = <0 0xeb3f0440 0 0x20>, + <0 0xeb3f0460 0 0x20>, + <0 0xeb3f0280 0 0x20>, + <0 0xeb3f02a0 0 0x20>; + reg-names = "local_request_region", "local_response_region", + "remote_request_region", "remote_response_region"; + #mbox-cells = <1>; + xlnx,ipi-id = <1>; + }; + }; +}; + +&cpu0 { + clocks = <&versal_net_clk ACPU_0>; +}; + +&cpu100 { + clocks = <&versal_net_clk ACPU_0>; +}; + +&cpu200 { + clocks = <&versal_net_clk ACPU_0>; +}; + +&cpu300 { + clocks = <&versal_net_clk ACPU_0>; +}; + +&cpu10000 { + clocks = <&versal_net_clk ACPU_1>; +}; + +&cpu10100 { + clocks = <&versal_net_clk ACPU_1>; +}; + +&cpu10200 { + clocks = <&versal_net_clk ACPU_1>; +}; + +&cpu10300 { + clocks = <&versal_net_clk ACPU_1>; +}; + +&cpu20000 { + clocks = <&versal_net_clk ACPU_2>; +}; + +&cpu20100 { + clocks = <&versal_net_clk ACPU_2>; +}; + +&cpu20200 { + clocks = <&versal_net_clk ACPU_2>; +}; + +&cpu20300 { + clocks = <&versal_net_clk ACPU_2>; +}; + +&cpu30000 { + clocks = <&versal_net_clk ACPU_3>; +}; + +&cpu30100 { + clocks = <&versal_net_clk ACPU_3>; +}; + +&cpu30200 { + clocks = <&versal_net_clk ACPU_3>; +}; + +&cpu30300 { + clocks = <&versal_net_clk ACPU_3>; +}; + +&can0 { + clocks = <&versal_net_clk CAN0_REF_2X>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_CAN_FD_0>; +}; + +&can1 { + clocks = <&versal_net_clk CAN1_REF_2X>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_CAN_FD_1>; +}; + +&gem0 { + clocks = <&versal_net_clk LPD_LSBUS>, + <&versal_net_clk GEM0_REF>, <&versal_net_clk GEM0_TX>, + <&versal_net_clk GEM0_RX>, <&versal_net_clk GEM_TSU>; + power-domains = <&versal_net_firmware PM_DEV_GEM_0>; +}; + +&gem1 { + clocks = <&versal_net_clk LPD_LSBUS>, + <&versal_net_clk GEM1_REF>, <&versal_net_clk GEM1_TX>, + <&versal_net_clk GEM1_RX>, <&versal_net_clk GEM_TSU>; + power-domains = <&versal_net_firmware PM_DEV_GEM_1>; +}; + +&gpio0 { + clocks = <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_GPIO>; +}; + +&gpio1 { + clocks = <&versal_net_clk PMC_LSBUS_REF>; + power-domains = <&versal_net_firmware PM_DEV_GPIO_PMC>; +}; + +&i2c0 { + clocks = <&versal_net_clk I3C0_REF>; + power-domains = <&versal_net_firmware PM_DEV_I2C_0>; +}; + +&i2c1 { + clocks = <&versal_net_clk I3C1_REF>; + power-domains = <&versal_net_firmware PM_DEV_I2C_1>; +}; + +&i3c0 { + clocks = <&versal_net_clk I3C0_REF>; + power-domains = <&versal_net_firmware PM_DEV_I2C_0>; +}; + +&i3c1 { + clocks = <&versal_net_clk I3C1_REF>; + power-domains = <&versal_net_firmware PM_DEV_I2C_1>; +}; + +&adma0 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_0>; +}; + +&adma1 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_1>; +}; + +&adma2 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_2>; +}; + +&adma3 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_3>; +}; + +&adma4 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_4>; +}; + +&adma5 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_5>; +}; + +&adma6 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_6>; +}; + +&adma7 { + clocks = <&versal_net_clk ADMA>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_ADMA_7>; +}; + +&qspi { + clocks = <&versal_net_clk QSPI_REF>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_QSPI>; +}; + +&ospi { + clocks = <&versal_net_clk OSPI_REF>; + power-domains = <&versal_net_firmware PM_DEV_OSPI>; + resets = <&versal_net_reset VERSAL_RST_OSPI>; +}; + +&rtc { + power-domains = <&versal_net_firmware PM_DEV_RTC>; +}; + +&serial0 { + clocks = <&versal_net_clk UART0_REF>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_UART_0>; +}; + +&serial1 { + clocks = <&versal_net_clk UART1_REF>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_UART_1>; +}; + +&sdhci0 { + clocks = <&versal_net_clk SDIO0_REF>, <&versal_net_clk LPD_LSBUS>, + <&versal_net_clk SD_DLL_REF>; + power-domains = <&versal_net_firmware PM_DEV_SDIO_0>; +}; + +&sdhci1 { + clocks = <&versal_net_clk SDIO1_REF>, <&versal_net_clk LPD_LSBUS>, + <&versal_net_clk SD_DLL_REF>; + power-domains = <&versal_net_firmware PM_DEV_SDIO_1>; +}; + +&spi0 { + clocks = <&versal_net_clk SPI0_REF>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_SPI_0>; +}; + +&spi1 { + clocks = <&versal_net_clk SPI1_REF>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_SPI_1>; +}; + +&ttc0 { + clocks = <&versal_net_clk TTC0>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_TTC_0>; +}; + +&ttc1 { + clocks = <&versal_net_clk TTC1>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_TTC_1>; +}; + +&ttc2 { + clocks = <&versal_net_clk TTC2>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_TTC_2>; +}; + +&ttc3 { + clocks = <&versal_net_clk TTC3>, <&versal_net_clk LPD_LSBUS>; + power-domains = <&versal_net_firmware PM_DEV_TTC_3>; +}; + +&usb0 { + clocks = <&versal_net_clk USB0_BUS_REF>, <&versal_net_clk USB0_BUS_REF>; + power-domains = <&versal_net_firmware PM_DEV_USB_0>; + resets = <&versal_net_reset VERSAL_RST_USB_0>; +}; + +&dwc3_0 { + clocks = <&versal_net_clk USB0_BUS_REF>; +}; + +&usb1 { + clocks = <&versal_net_clk USB1_BUS_REF>, <&versal_net_clk USB1_BUS_REF>; + power-domains = <&versal_net_firmware PM_DEV_USB_1>; + resets = <&versal_net_reset VERSAL_RST_USB_1>; +}; + +&dwc3_1 { + clocks = <&versal_net_clk USB1_BUS_REF>; +}; + +&wwdt0 { + clocks = <&versal_net_clk FPD_WWDT0>; + power-domains = <&versal_net_firmware PM_DEV_FPD_SWDT_0>; +}; + +&wwdt1 { + clocks = <&versal_net_clk FPD_WWDT1>; + power-domains = <&versal_net_firmware PM_DEV_FPD_SWDT_1>; +}; + +&wwdt2 { + clocks = <&versal_net_clk FPD_WWDT2>; + power-domains = <&versal_net_firmware PM_DEV_FPD_SWDT_2>; +}; + +&wwdt3 { + clocks = <&versal_net_clk FPD_WWDT3>; + power-domains = <&versal_net_firmware PM_DEV_FPD_SWDT_3>; +}; + +&lpd_wwdt0 { + clocks = <&versal_net_clk LPD_WWDT0>; + power-domains = <&versal_net_firmware PM_DEV_LPD_SWDT_0>; +}; + +&lpd_wwdt1 { + clocks = <&versal_net_clk LPD_WWDT1>; + power-domains = <&versal_net_firmware PM_DEV_LPD_SWDT_1>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-net-clk.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-net-clk.dtsi @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal NET fixed clock + * + * (C) Copyright 2022, Xilinx, Inc. + * + * Michal Simek + */ + +#include + +/ { + clk60: clk60 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <60000000>; + }; + + clk100: clk100 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + clk125: clk125 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clk150: clk150 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <150000000>; + }; + + clk160: clk160 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <160000000>; + }; + + clk200: clk200 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + }; + + clk250: clk250 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + }; + + clk300: clk300 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <300000000>; + }; + + clk450: clk450 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <450000000>; + }; + + clk1200: clk1200 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1200000000>; + }; + + firmware { + versal_net_firmware: versal-net-firmware { + compatible = "xlnx,versal-net-firmware", "xlnx,versal-firmware"; + bootph-all; + method = "smc"; + + versal_net_reset: reset-controller { + compatible = "xlnx,versal-net-reset"; + #reset-cells = <1>; + }; + }; + }; +}; + +&adma0 { + clocks = <&clk450>, <&clk450>; +}; + +&adma1 { + clocks = <&clk450>, <&clk450>; +}; + +&adma2 { + clocks = <&clk450>, <&clk450>; +}; + +&adma3 { + clocks = <&clk450>, <&clk450>; +}; + +&adma4 { + clocks = <&clk450>, <&clk450>; +}; + +&adma5 { + clocks = <&clk450>, <&clk450>; +}; + +&adma6 { + clocks = <&clk450>, <&clk450>; +}; + +&adma7 { + clocks = <&clk450>, <&clk450>; +}; + +&can0 { + clocks = <&clk160>, <&clk160>; +}; + +&can1 { + clocks = <&clk160>, <&clk160>; +}; + +&gem0 { + clocks = <&clk125>, <&clk125>, <&clk125>, <&clk125>, <&clk250>; +}; + +&gem1 { + clocks = <&clk125>, <&clk125>, <&clk125>, <&clk125>, <&clk250>; +}; + +&gpio0 { + clocks = <&clk100>; +}; + +&gpio1 { + clocks = <&clk100>; +}; + +&i2c0 { + clocks = <&clk100>; +}; + +&i2c1 { + clocks = <&clk100>; +}; + +&i3c0 { + clocks = <&clk100>; +}; + +&i3c1 { + clocks = <&clk100>; +}; + +&ospi { + clocks = <&clk200>; + resets = <&versal_net_reset VERSAL_RST_OSPI>; +}; + +&qspi { + clocks = <&clk300>, <&clk300>; +}; + +&rtc { + /* Nothing */ +}; + +&sdhci0 { + clocks = <&clk200>, <&clk200>, <&clk1200>; +}; + +&sdhci1 { + clocks = <&clk200>, <&clk200>, <&clk1200>; +}; + +&serial0 { + clocks = <&clk100>, <&clk100>; + clock = <1000000>; +}; + +&serial1 { + clocks = <&clk100>, <&clk100>; + clock = <100000000>; +}; + +&spi0 { + clocks = <&clk200>, <&clk200>; +}; + +&spi1 { + clocks = <&clk200>, <&clk200>; +}; + +&ttc0 { + clocks = <&clk150>; +}; + +&usb0 { + clocks = <&clk60>, <&clk60>; +}; + +&dwc3_0 { + /* Nothing */ +}; + +&usb1 { + clocks = <&clk60>, <&clk60>; +}; + +&dwc3_1 { + /* Nothing */ +}; + +&wwdt0 { + clocks = <&clk150>; +}; + +&wwdt1 { + clocks = <&clk150>; +}; + +&wwdt2 { + clocks = <&clk150>; +}; + +&wwdt3 { + clocks = <&clk150>; +}; + +&lpd_wwdt0 { + clocks = <&clk150>; +}; + +&lpd_wwdt1 { + clocks = <&clk150>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-net-vn-p-b2197-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-net-vn-p-b2197-00-revA.dts @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197-00 (Tenzing2) + * + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include "versal-net.dtsi" +#include "versal-net-clk-ccf.dtsi" + +/ { + compatible = "xlnx,versal-net-vn-p-b2197-00-revA", + "xlnx,versal-net-vn-p-b2197-00", "xlnx,versal-net"; + + memory: memory@0 { + reg = <0 0 0 0x80000000>; + device_type = "memory"; + }; + + chosen { + bootargs = "earlycon=pl011,mmio32,0xf1920000 console=ttyAMA0,115200n8 root=/dev/ram0 rw"; + stdout-path = "serial0:115200n8"; + }; + +/* aliases { + nvmem0 = &eeprom0; + nvmem1 = &eeprom1; + }; */ +}; + +&i2c0 { + /* Access via J70/J71 or J82/J83 */ + clock-frequency = <100000>; +}; + +&i2c1 { + /* Access via J70/J71 or J82/J83 */ + /* By default this bus should have eeprom for board identification at 0x54 */ + /* SE/X-PRC card identification is also on this bus at 0x52 */ + clock-frequency = <100000>; +}; + +&adma0 { + status = "okay"; +}; + +&adma1 { + status = "okay"; +}; + +&adma2 { + status = "okay"; +}; + +&adma3 { + status = "okay"; +}; + +&adma4 { + status = "okay"; +}; + +&adma5 { + status = "okay"; +}; + +&adma6 { + status = "okay"; +}; + +&adma7 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sysmon0 { + status = "okay"; +}; + +&wwdt0 { + status = "okay"; +}; + +&wwdt1 { + status = "okay"; +}; + +&wwdt2 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-net-vn-x-b2197-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-net-vn-x-b2197-01-revA.dts @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal Net VNX board revA + * + * (C) Copyright 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include "versal-net.dtsi" +#include "versal-net-clk-ccf.dtsi" +#include +#include + +/ { + compatible = "xlnx,versal-net-vnx-revA", "xlnx,versal-net-vnx", "xlnx,versal-net"; + model = "Xilinx Versal NET VNX revA"; + dma-coherent; + + memory: memory@0 { + reg = <0 0 0 0x80000000>; + device_type = "memory"; + }; + + memory_hi: memory@800000000 { + reg = <8 0 3 0x80000000>; + device_type = "memory"; + }; + + memory_hi2: memory@50000000000 { + reg = <0x500 0 4 0>; + device_type = "memory"; + }; + + chosen { + bootargs = "console=ttyAMA1,115200n8"; + stdout-path = "serial1:115200n8"; + }; + + cdx { + compatible = "xlnx,versal-net-cdx"; + status = "okay"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges = <0 0 0 0 0x10000 0>; + iommu-map = <0x0 &smmu 0x0 0xfffff>; + msi-map = <0x0 &its 0x0 0xffff>; + xlnx,rproc = <&remoteproc_r52>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + rsc_tbl_carveout: rproc@bbf14000 { + reg = <0 0xbbf14000 0 0x1000>; + no-map; + }; + rpu0vdev0vring0: rpu0vdev0vring0@bbf15000 { + reg = <0 0xbbf15000 0 0x1000>; + no-map; + }; + rpu0vdev0vring1: rpu0vdev0vring1@bbf16000 { + reg = <0 0xbbf16000 0 0x1000>; + no-map; + }; + rpu0vdev0buffer: rpu0vdev0buffer@bbf17000 { + reg = <0 0xbbf17000 0 0xD000>; + no-map; + }; + reserve_others: reserveothers@0 { + reg = <0 0x0 0 0x1c200000>; + no-map; + }; + pdi_update: pdiupdate@1c200000 { + reg = <0 0x1c200000 0 0x6000000>; + no-map; + }; + reserve_optee_atf: reserveopteeatf@22200000 { + reg = <0 0x22200000 0 0x4100000>; + no-map; + }; + }; + + zynqmp_ipi1_nobuf { + compatible = "xlnx,versal-ipi-mailbox"; + reg = <0x00 0xeb3b0000 0x00 0x1ff>; + reg-names = "ctrl"; + status = "okay"; + interrupts = <0 64 4>; + xlnx,ipi-id = <10>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + ipi_mailbox_rpu0: mailbox@eb3b1000 { + #mbox-cells = <1>; + xlnx,ipi-id = <11>; + reg = <0 0xeb3b1000 0 0x1000>; + reg-names = "ctrl"; + }; + }; + + r52ss@ff9a0000 { + compatible = "xlnx,versal-net-r52-remoteproc"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0 0xff9a0000 0 0x10000>; + xlnx,cluster-mode = <1>; + remoteproc_r52: r52_0 { + compatible = "xilinx,r52"; + memory-region = <&rsc_tbl_carveout>, <&rpu0vdev0buffer>, + <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; + power-domain = <&versal_net_firmware PM_DEV_RPU_A_0>; + mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; + mbox-names = "tx", "rx"; + xlnx,rsc-tbl = <&rsc_tbl_carveout 0xbbf14000>; + }; + }; +}; + +&gem1 { + status = "okay"; + iommus = <&smmu 0x235>; + phy-handle = <&phy>; + phy-mode = "rmii"; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy: ethernet-phy@4 { + reg = <4>; + }; + }; +}; + +&ospi { + num-cs = <2>; + iommus = <&smmu 0x245>; + reset-names = "qspi"; + #address-cells = <1>; + #size-cells = <0>; + reset-names = "qspi"; + mt35xu02g: flash@0 { + compatible = "micron,m25p80", "jedec,spi-nor"; + reg = <0>, <1>; + stacked-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + #address-cells = <1>; + #size-cells = <1>; + cdns,read-delay = <0>; + cdns,tshsl-ns = <0>; + cdns,tsd2d-ns = <0>; + cdns,tchsh-ns = <1>; + cdns,tslch-ns = <1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + broken-flash-reset; + reset-gpios = <&gpio1 0xc GPIO_ACTIVE_LOW>; + }; +}; + +&usb1 { + iommus = <&smmu 0x232>; +}; + +&sdhci1 { + status = "okay"; + iommus = <&smmu 0x243>; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + no-1-8-v; +}; + +&serial1 { + status = "okay"; + skip-init; +}; + +&smmu { + status = "okay"; +}; + +&versal_fpga { + dma-noncoherent; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-net.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-net.dtsi @@ -0,0 +1,818 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal NET + * + * Copyright (C) 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +/ { + compatible = "xlnx,versal-net"; + model = "Xilinx Versal NET"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + options { + u-boot { + compatible = "u-boot,config"; + bootscr-address = /bits/ 64 <0x20000000>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu100>; + }; + core2 { + cpu = <&cpu200>; + }; + core3 { + cpu = <&cpu300>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu10000>; + }; + + core1 { + cpu = <&cpu10100>; + }; + + core2 { + cpu = <&cpu10200>; + }; + + core3 { + cpu = <&cpu10300>; + }; + }; + cluster2 { + core0 { + cpu = <&cpu20000>; + }; + + core1 { + cpu = <&cpu20100>; + }; + + core2 { + cpu = <&cpu20200>; + }; + + core3 { + cpu = <&cpu20300>; + }; + }; + cluster3 { + core0 { + cpu = <&cpu30000>; + }; + + core1 { + cpu = <&cpu30100>; + }; + + core2 { + cpu = <&cpu30200>; + }; + + core3 { + cpu = <&cpu30300>; + }; + }; + + }; + + cpu0: cpu@0 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu100: cpu@100 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x100>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu200: cpu@200 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x200>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu300: cpu@300 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x300>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu10000: cpu@10000 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x10000>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu10100: cpu@10100 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x10100>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu10200: cpu@10200 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x10200>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu10300: cpu@10300 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x10300>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu20000: cpu@20000 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x20000>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu20100: cpu@20100 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x20100>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu20200: cpu@20200 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x20200>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu20300: cpu@20300 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x20300>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu30000: cpu@30000 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x30000>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu30100: cpu@30100 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x30100>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu30200: cpu@30200 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x30200>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + cpu30300: cpu@30300 { + compatible = "arm,cortex-a78"; + device_type = "cpu"; + enable-method = "psci"; + reg = <0x30300>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x40000000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <600>; + min-residency-us = <10000>; + }; + }; + }; + + cpu_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-1066000000 { + opp-hz = /bits/ 64 <1066000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-1866000000 { + opp-hz = /bits/ 64 <1866000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-1900000000 { + opp-hz = /bits/ 64 <1900000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-1999000000 { + opp-hz = /bits/ 64 <1999000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-2050000000 { + opp-hz = /bits/ 64 <2050000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-2100000000 { + opp-hz = /bits/ 64 <2100000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-2200000000 { + opp-hz = /bits/ 64 <2200000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp-2400000000 { + opp-hz = /bits/ 64 <2400000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &dcc; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + i2c0 = &i2c0; + i2c1 = &i2c1; + rtc = &rtc; + usb0 = &usb0; + usb1 = &usb1; + spi0 = &ospi; + spi1 = &qspi; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; + bootph-all; + }; + + firmware { + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + }; + + fpga: fpga-region { + compatible = "fpga-region"; + fpga-mgr = <&versal_fpga>; + #address-cells = <2>; + #size-cells = <2>; + }; + + timer: timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 4>, <1 14 4>, <1 11 4>, <1 10 4>; /* FIXME 3rd cell */ + }; + + versal_fpga: versal-fpga { + compatible = "xlnx,versal-fpga"; + }; + + sensor0: versal-thermal-sensor { + compatible = "xlnx,versal-thermal"; + #thermal-sensor-cells = <0>; + io-channels = <&sysmon0>; + io-channel-names = "sysmon-temp-channel"; + }; + + thermal-zones { + versal_thermal: versal-thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + thermal-sensors = <&sensor0>; + + trips { + temp_alert: temp-alert { + temperature = <70000>; /* millicelsius */ + hysteresis = <0>; /* millicelsius */ + type = "passive"; + }; + + ot_crit: ot-crit { + temperature = <125000>; /* millicelsius */ + hysteresis = <0>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; + + amba: axi { + compatible = "simple-bus"; + bootph-all; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + adma0: dma-controller@ebd00000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd00000 0 0x1000>; + interrupts = <0 72 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x210>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma1: dma-controller@ebd10000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd10000 0 0x1000>; + interrupts = <0 73 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x212>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma2: dma-controller@ebd20000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd20000 0 0x1000>; + interrupts = <0 74 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x214>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma3: dma-controller@ebd30000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd30000 0 0x1000>; + interrupts = <0 75 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x216>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma4: dma-controller@ebd40000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd40000 0 0x1000>; + interrupts = <0 76 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x218>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma5: dma-controller@ebd50000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd50000 0 0x1000>; + interrupts = <0 77 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x21A>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma6: dma-controller@ebd60000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd60000 0 0x1000>; + interrupts = <0 78 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x21C>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + adma7: dma-controller@ebd70000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xebd70000 0 0x1000>; + interrupts = <0 79 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x21E>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + }; + + can0: can@f1980000 { + compatible = "xlnx,canfd-2.0"; + status = "disabled"; + reg = <0 0xf1980000 0 0x6000>; + interrupts = <0 27 4>; + clock-names = "can_clk", "s_axi_aclk"; + rx-fifo-depth = <64>; + tx-mailbox-count = <32>; + }; + + can1: can@f1990000 { + compatible = "xlnx,canfd-2.0"; + status = "disabled"; + reg = <0 0xf1990000 0 0x6000>; + interrupts = <0 28 4>; + clock-names = "can_clk", "s_axi_aclk"; + rx-fifo-depth = <64>; + tx-mailbox-count = <32>; + }; + + gem0: ethernet@f19e0000 { + compatible = "xlnx,versal-gem", "cdns,gem"; + status = "disabled"; + reg = <0 0xf19e0000 0 0x1000>; + interrupts = <0 39 4>, <0 39 4>; + clock-names = "pclk", "hclk", "tx_clk", "rx_clk", + "tsu_clk"; + /* iommus = <&smmu 0x234>; */ + }; + + gem1: ethernet@f19f0000 { + compatible = "xlnx,versal-gem", "cdns,gem"; + status = "disabled"; + reg = <0 0xf19f0000 0 0x1000>; + interrupts = <0 41 4>, <0 41 4>; + clock-names = "pclk", "hclk", "tx_clk", "rx_clk", + "tsu_clk"; + /* iommus = <&smmu 0x235>; */ + }; + + gic: interrupt-controller@e2000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + reg = <0 0xe2000000 0 0x10000>, + <0 0xe2060000 0 0x200000>; + interrupt-controller; + interrupts = <1 9 4>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + its: msi-controller@e2040000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0 0xe2040000 0 0x20000>; + }; + }; + + gpio0: gpio@f19d0000 { + compatible = "xlnx,versal-gpio-1.0"; + status = "disabled"; + reg = <0 0xf19d0000 0 0x1000>; + interrupts = <0 20 4>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio1: gpio@f1020000 { + compatible = "xlnx,pmc-gpio-1.0"; + status = "disabled"; + reg = <0 0xf1020000 0 0x1000>; + interrupts = <0 180 4>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + i2c0: i2c@f1940000 { + compatible = "cdns,i2c-r1p14"; + status = "disabled"; + reg = <0 0xf1940000 0 0x1000>; + interrupts = <0 21 4>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@f1950000 { + compatible = "cdns,i2c-r1p14"; + status = "disabled"; + reg = <0 0xf1950000 0 0x1000>; + interrupts = <0 22 4>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i3c0: i3c@f1948000 { + compatible = "snps,dw-i3c-master-1.00a"; + status = "disabled"; + reg = <0 0xf1948000 0 0x1000>; + #address-cells = <3>; + #size-cells = <0>; + interrupts = <0 21 4>; + }; + + i3c1: i3c@f1958000 { + compatible = "snps,dw-i3c-master-1.00a"; + status = "disabled"; + reg = <0 0xf1958000 0 0x1000>; + #address-cells = <3>; + #size-cells = <0>; + interrupts = <0 22 4>; + }; + + ospi: spi@f1010000 { + compatible = "xlnx,versal-ospi-1.0", "cdns,qspi-nor"; + status = "disabled"; + reg = <0 0xf1010000 0 0x10000>, + <0 0xc0000000 0 0x20000000>; + interrupts = <0 182 4>; + /* iommus = <&smmu 0x245>; */ + cdns,fifo-depth = <256>; + cdns,fifo-width = <4>; + cdns,is-dma = <1>; /* u-boot specific */ + /* cdns,is-stig-pgm = <1>; - unused - checking with Sai */ + cdns,trigger-address = <0xc0000000>; + }; + + qspi: spi@f1030000 { + compatible = "xlnx,versal-qspi-1.0"; + status = "disabled"; + reg = <0 0xf1030000 0 0x1000>; /* missing one more reg range - checking with Sai */ + interrupts = <0 183 4>; + clock-names = "ref_clk", "pclk"; + /* iommus = <&smmu 0x244>; */ + }; + + rtc: rtc@f12a0000 { + compatible = "xlnx,zynqmp-rtc"; + status = "disabled"; + reg = <0 0xf12a0000 0 0x100>; + interrupts = <0 200 4>, <0 201 4>; + interrupt-names = "alarm", "sec"; + calibration = <0x8000>; + }; + + sdhci0: mmc@f1040000 { + compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; + status = "disabled"; + reg = <0 0xf1040000 0 0x10000>; + interrupts = <0 184 4>; + clock-names = "clk_xin", "clk_ahb", "gate"; + /* iommus = <&smmu 0x242>; */ + #clock-cells = <1>; + clock-output-names = "clk_out_sd0", "clk_in_sd0"; + }; + + sdhci1: mmc@f1050000 { + compatible = "xlnx,versal-net-emmc"; + status = "disabled"; + reg = <0 0xf1050000 0 0x10000>; + interrupts = <0 186 4>; + clock-names = "clk_xin", "clk_ahb", "gate"; + /* iommus = <&smmu 0x243>; */ + #clock-cells = <1>; + clock-output-names = "clk_out_sd1", "clk_in_sd1"; + }; + + serial0: serial@f1920000 { + bootph-all; + compatible = "arm,pl011", "arm,primecell"; + status = "disabled"; + reg = <0 0xf1920000 0 0x1000>; + interrupts = <0 25 4>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + }; + + serial1: serial@f1930000 { + bootph-all; + compatible = "arm,pl011", "arm,primecell"; + status = "disabled"; + reg = <0 0xf1930000 0 0x1000>; + interrupts = <0 26 4>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + }; + + smmu: iommu@ec000000 { + compatible = "arm,smmu-v3"; + status = "disabled"; + reg = <0 0xec000000 0 0x40000>; + #iommu-cells = <1>; + interrupt-names = "combined"; + interrupts = <0 169 4>; + dma-coherent; + }; + + spi0: spi@f1960000 { + compatible = "cdns,spi-r1p6"; + status = "disabled"; + interrupts = <0 23 4>; + reg = <0 0xf1960000 0 0x1000>; + clock-names = "ref_clk", "pclk"; + }; + + spi1: spi@f1970000 { + compatible = "cdns,spi-r1p6"; + status = "disabled"; + interrupts = <0 24 4>; + reg = <0 0xf1970000 0 0x1000>; + clock-names = "ref_clk", "pclk"; + }; + + sysmon0: sysmon@f1270000 { + compatible = "xlnx,versal-sysmon"; + status = "disabled"; + #io-channel-cells = <0>; + reg = <0x0 0xf1270000 0x0 0x4000>; + interrupts = <0 202 4>; + xlnx,numchannels = /bits/8 <0>; + }; + + ttc0: timer@f1dc0000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 43 4>, <0 44 4>, <0 45 4>; + timer-width = <32>; + reg = <0x0 0xf1dc0000 0x0 0x1000>; + }; + + ttc1: timer@f1dd0000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 46 4>, <0 47 4>, <0 48 4>; + timer-width = <32>; + reg = <0x0 0xf1dd0000 0x0 0x1000>; + }; + + ttc2: timer@f1de0000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 49 4>, <0 50 4>, <0 51 4>; + timer-width = <32>; + reg = <0x0 0xf1de0000 0x0 0x1000>; + }; + + ttc3: timer@f1df0000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 52 4>, <0 53 4>, <0 54 4>; + timer-width = <32>; + reg = <0x0 0xf1df0000 0x0 0x1000>; + }; + + usb0: usb@f1e00000 { + compatible = "xlnx,versal-dwc3"; + status = "disabled"; + reg = <0 0xf1e00000 0 0x100>; + clock-names = "bus_clk", "ref_clk"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + + dwc3_0: usb@f1b00000 { + compatible = "snps,dwc3"; + status = "disabled"; + reg = <0 0xf1b00000 0 0x10000>; + interrupt-names = "host", "peripheral", "otg", "wakeup"; + interrupts = <0 29 4>, <0 29 4>, <0 33 4>, <0 98 4>; + /* iommus = <&smmu 0x230>; */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,quirk-frame-length-adjustment = <0x20>; + dr_mode = "peripheral"; + maximum-speed = "high-speed"; + snps,usb3_lpm_capable; + clock-names = "ref"; + /* phy-names = "usb3-phy";- checking with Pyiush */ + }; + }; + + usb1: usb@f1e10000 { + compatible = "xlnx,versal-dwc3"; + status = "disabled"; + reg = <0x0 0xf1e10000 0x0 0x100>; + clock-names = "bus_clk", "ref_clk"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + + dwc3_1: usb@f1c00000 { + compatible = "snps,dwc3"; + status = "disabled"; + reg = <0x0 0xf1c00000 0x0 0x10000>; + interrupt-names = "host", "peripheral", "otg", "wakeup"; + interrupts = <0 34 4>, <0 34 4>, <0 38 4>, <0 99 4>; + /* iommus = <&smmu 0x232>; */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,quirk-frame-length-adjustment = <0x20>; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,usb3_lpm_capable; + clock-names = "ref"; + /* phy-names = "usb3-phy"; - checking with Pyiush */ + }; + }; + + wwdt0: watchdog@ecc10000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xecc10000 0 0x10000>; + timeout-sec = <30>; + }; + + wwdt1: watchdog@ecd10000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xecd10000 0 0x10000>; + timeout-sec = <30>; + }; + + wwdt2: watchdog@ece10000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xece10000 0 0x10000>; + timeout-sec = <30>; + }; + + wwdt3: watchdog@ecf10000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xecf10000 0 0x10000>; + timeout-sec = <30>; + }; + + lpd_wwdt0: watchdog@ea420000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xea420000 0 0x10000>; + timeout-sec = <30>; + }; + + lpd_wwdt1: watchdog@ea430000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xea430000 0 0x10000>; + timeout-sec = <30>; + }; + + xilsem_edac: edac@f2014050 { + compatible = "xlnx,versal-xilsem-edac"; + status = "disabled"; + reg = <0x0 0xf2014050 0x0 0xc4>; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-v350-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-v350-revA.dts @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal v350 revA + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" +#include + +/ { + compatible = "xlnx,versal-v350-revA", "xlnx,versal"; + model = "Xilinx Versal v350 board revA"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF010000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &dcc; + spi0 = &ospi; + }; + + memory: memory@0 { + device_type = "memory"; /* 16GB total via MC0/1/2/3 */ + reg = <0 0 0 0x80000000>; /* 2GB here */ + /* <0x8 0x0 0x3 0x80000000> */ /* 12GB - enable it later */ + }; +}; + +&ospi { + status = "okay"; + bus-num = <2>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <0x1>; + #size-cells = <0x1>; + cdns,read-delay = <0x0>; + cdns,tshsl-ns = <0x0>; + cdns,tsd2d-ns = <0x0>; + cdns,tchsh-ns = <0x1>; + cdns,tslch-ns = <0x1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 0xc GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&dcc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "disabled"; /* communication with MSP432 */ +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-01-revA-ospi.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-01-revA-ospi.dts @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-01 revA (SE1) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA-x-prc-01-revA.dts" +#include + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA-x-prc-01-revA", + "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA - x-prc-01 revA OSPI"; + + aliases { + spi0 = &ospi; + }; +}; + +/* Mutually exclusive */ +&ospi { + status = "okay"; /* U97 MT35XU02G */ + bus-num = <2>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + reset-names = "qspi"; + resets = <&versal_reset VERSAL_RST_OSPI>; + + flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <0x1>; + #size-cells = <0x1>; + cdns,read-delay = <0x0>; + cdns,tshsl-ns = <0x0>; + cdns,tsd2d-ns = <0x0>; + cdns,tchsh-ns = <0x1>; + cdns,tslch-ns = <0x1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 0xc GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&qspi { + status = "disabled"; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-01-revA.dts @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-01 revA (SE1) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA.dts" + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA-x-prc-01-revA", + "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA - x-prc-01 revA QSPI"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + ethernet0 = &gem0; + ethernet1 = &gem1; + i2c0 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + rtc0 = &rtc; + }; +}; + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&qspi { + status = "okay"; /* u93 and u92 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <35000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&sdhci1 { /* U104 */ + status = "okay"; + xlnx,mio-bank = <1>; +}; + +&serial0 { + status = "okay"; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy1>; /* u128 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + }; + phy2: phy@2 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <2>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + }; + }; +}; + +&gem1 { + status = "okay"; + phy-handle = <&phy2>; /* u134 */ + phy-mode = "rgmii-id"; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + eeprom_versal: eeprom@51 { /* U116 */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + }; + + /* FIXME - U117 and U118 */ +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host - U99 */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; + phy-names = "usb3-phy"; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-02-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-02-revA.dts @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-02 revA (SE2) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA.dts" + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA-x-prc-02-revA", + "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA - x-prc-02 revA"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + ethernet0 = &gem0; + i2c0 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + spi0 = &spi0; + spi1 = &spi1; + usb0 = &usb0; + }; +}; + +&serial0 { + status = "okay"; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; /* u9 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@1 { /* Marvell 88E1512; U9 */ + reg = <1>; + }; + }; +}; + +&sdhci0 { + status = "okay"; + xlnx,mio-bank = <1>; +}; + +&sdhci1 { /* U1A */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { /* U4 */ + status = "okay"; + dr_mode = "peripheral"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + maximum-speed = "high-speed"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + /* U12 Catalyst EEPROM - AT24 should be equivalent */ + eeprom_versal: eeprom@51 { + compatible = "atmel,24c128"; + reg = <0x51>; + }; + + /* FIXME - U13 and U15 */ +}; + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&spi0 { + status = "okay"; + num-cs = <1>; + + flash@0 { /* U18 */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "sst,sst25vf016b", "m25p80", "jedec,spi-nor"; + spi-max-frequency = <25000000>; + reg = <0>; + + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x200000>; + }; + }; +}; + +&spi1 { + status = "okay"; + num-cs = <3>; /* FIXME - check SPI1_SS0-2_B */ + + flash@0 { /* U19 */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "sst,sst26vf016b", "m25p80", "jedec,spi-nor"; + spi-max-frequency = <25000000>; + reg = <0>; + + partition@0 { + label = "spi1-flash0"; + reg = <0x0 0x200000>; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-03-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-03-revA.dts @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-03 revA (SE3) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA.dts" + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA-x-prc-03-revA", + "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA - x-prc-03 revA"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + can0 = &can0; + can1 = &can1; + i2c0 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + serial0 = &serial0; + spi0 = &qspi; + spi1 = &spi0; + }; +}; + +/* SMAP via cc108 */ + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + /* Must be enabled via J90/J91 */ + eeprom_versal: eeprom@51 { /* U2 - 128kb RM24C128DS */ + compatible = "atmel,24c128"; + reg = <0x51>; + }; +}; + +&qspi { + status = "okay"; /* u7 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80", "jedec,spi-nor"; /* 64Mb */ + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x800000>; + }; + }; +}; + +&serial0 { + status = "okay"; +}; + +&sdhci0 { /* J99 MIO28 - MIO33 */ + status = "okay"; + xlnx,mio-bank = <1>; /* FIXME */ +}; + +&sdhci1 { /* EMMC IS21ES08G 200MHz MIO40 - MIO49 */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; /* FIXME */ +}; + +&spi0 { + status = "okay"; + num-cs = <1>; + + flash@0 { /* U6 - IS25LQ032B - 16Mb */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "issi,is25lq032b", "m25p80", "jedec,spi-nor"; + spi-max-frequency = <104000000>; + reg = <0>; + + partition@0 { + label = "spi0-flash0"; + reg = <0 0x200000>; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-04-revA-ospi.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-04-revA-ospi.dts @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-04 revA (SE4) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA-x-prc-04-revA.dts" + +/ { + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + spi0 = &ospi; + }; +}; + +/* Mutually exclusive with qspi */ +&ospi { + status = "okay"; /* U163/U97 MT35XU02G */ +}; + +&qspi { + status = "disabled"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-04-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-04-revA.dts @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-04 revA (SE4) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA.dts" + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA-x-prc-04-revA", + "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA - x-prc-04 revA"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + ethernet1 = &gem1; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + spi1 = &spi0; + usb0 = &usb0; + }; +}; + +&gem1 { + status = "okay"; + phy-handle = <&phy1>; /* u175 */ + phy-mode = "rgmii-id"; /* RTL8211DN */ + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { + reg = <2>; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + eeprom_versal: eeprom@51 { /* U153 */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + eeprom: eeprom@51 { /* U155 */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + }; +}; + +&qspi { + status = "okay"; /* u93 and u92 and u161 and u160 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80", "jedec,spi-nor"; /* 512MB */ + reg = <0>, <1>; + stacked-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x20000000>; + }; + }; +}; + +&sdhci1 { /* J3 MIO26, MIO29 - MIO33 */ + status = "okay"; + disable-wp; + xlnx,mio-bank = <1>; /* FIXME */ +}; + +&serial0 { /* MIO35 - MIO37 */ + status = "okay"; +}; + +&serial1 { /* MIO4 - MIO7 RS232 */ + status = "okay"; +}; + +&spi0 { + status = "okay"; + num-cs = <1>; + + flash@0 { /* U171 - IS25LP016B - 16Mb */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "issi,is25lp016b", "m25p80", "jedec,spi-nor"; + spi-max-frequency = <104000000>; + reg = <0>; + + partition@0 { + label = "spi0-flash0"; + reg = <0 0x200000>; + }; + }; +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host - U99 */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; + phy-names = "usb3-phy"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-05-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA-x-prc-05-revA.dts @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal X-PRC-05 revA (SE5) + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vc-p-a2197-00-revA.dts" +#include + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA-x-prc-05-revA", + "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA - x-prc-05 revA"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + ethernet0 = &gem0; + ethernet1 = &gem1; + i2c0 = &i2c0; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + }; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { /* 88e1510 */ + reg = <1>; + }; + phy2: phy@2 { /* VSC8531 */ + reg = <2>; + rx-internal-delay-ps = <2600>; + tx-internal-delay-ps = <2600>; + }; + }; +}; + +&gem1 { + status = "okay"; + phy-handle = <&phy2>; + phy-mode = "rgmii-id"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + eeprom_versal: eeprom@51 { + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + }; +}; + +&qspi { + status = "okay"; + num-cs = <0x1>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + flash@0 { /* MX25U12835 128Mbit */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80", "jedec,spi-nor"; /* 16MB */ + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <104000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x1000000>; + }; + }; +}; + +&sdhci0 { /* emmc0 */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; /* FIXME */ +}; + +&sdhci1 { /* connector */ + status = "okay"; + xlnx,mio-bank = <1>; /* FIXME */ +}; + +&serial0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; + phy-names = "usb3-phy"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vc-p-a2197-00-revA.dts @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + compatible = "xlnx,versal-vc-p-a2197-00-revA", + "xlnx,versal-vc-p-a2197-00", + "xlnx,versal-vc-p-a2197", "xlnx,versal"; + model = "Xilinx Versal A2197 Processor board revA"; + + aliases { + serial2 = &dcc; + }; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x1 0x80000000>; + }; +}; + +&dcc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&sdhci0 { + no-1-8-v; +}; + +&sdhci1 { + no-1-8-v; +}; + +&watchdog { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1-x-ebm-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1-x-ebm-01-revA.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 rev1.1 with X-EBM-01-revA module + * + * (C) Copyright 2019 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1-x-ebm-01-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-rev1.1-x-ebm-01-revA", + "xlnx,versal-vck190-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board rev1.1 (QSPI)"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1-x-ebm-02-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1-x-ebm-02-revA.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 rev1.1 with X-EBM-02-revA module + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1-x-ebm-02-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-rev1.1-x-ebm-02-revA", + "xlnx,versal-vck190-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board rev1.1 (EMMC)"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1-x-ebm-03-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1-x-ebm-03-revA.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 rev1.1 with X-EBM-03-revA module + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1-x-ebm-03-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-rev1.1-x-ebm-03-revA", + "xlnx,versal-vck190-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board rev1.1 (OSPI)"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-rev1.1.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 rev1.1 + * + * (C) Copyright 2019 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1.dts" + +/ { + compatible = "xlnx,versal-vck190-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board rev1.1"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-revA-x-ebm-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-revA-x-ebm-01-revA.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 revA with X-EBM-01-revA module + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA-x-ebm-01-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-revA-x-ebm-01-revA", + "xlnx,versal-vck190-revA", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board revA (QSPI)"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-revA-x-ebm-02-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-revA-x-ebm-02-revA.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 revA with X-EBM-02-revA module + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA-x-ebm-02-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-revA-x-ebm-02-revA", + "xlnx,versal-vck190-revA", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board revA (EMMC)"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-revA-x-ebm-03-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-revA-x-ebm-03-revA.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 revA with X-EBM-03-revA module + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA-x-ebm-03-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-revA-x-ebm-03-revA", + "xlnx,versal-vck190-revA", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board revA (OSPI)"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck190-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck190-revA.dts @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck190 revA + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA.dts" + +/ { + compatible = "xlnx,versal-vck190-revA", "xlnx,versal"; + model = "Xilinx Versal vck190 Eval board revA"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vck5000-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vck5000-revA.dts @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vck5000 revA + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" +#include + +/ { + compatible = "xlnx,versal-vck5000-revA", "xlnx,versal"; + model = "Xilinx Versal vck5000 board revA"; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &dcc; + spi0 = &ospi; + }; + + memory: memory@0 { + device_type = "memory"; /* 16GB total via MC0/1/2/3 */ + reg = <0 0 0 0x80000000>, <0x8 0x0 0x3 0x80000000>; + }; +}; + +&ospi { + status = "okay"; + bus-num = <2>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <0x1>; + #size-cells = <0x1>; + cdns,read-delay = <0x0>; + cdns,tshsl-ns = <0x0>; + cdns,tsd2d-ns = <0x0>; + cdns,tchsh-ns = <0x1>; + cdns,tslch-ns = <0x1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 0xc GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x10000000>; + }; + }; +}; + +&dcc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "disabled"; /* communication with MSP432 */ +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vek280-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vek280-revA.dts @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal VEK280 revA + * + * (C) Copyright 2022, Advanced Micro Devices, Inc + * + * Michal Simek + */ + +#include +#include +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + compatible = "xlnx,versal-vek280-revA", "xlnx,versal-vek280", + "xlnx,versal"; + model = "Xilinx Versal vek280 Eval board revA"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x1 0x80000000>; /* 2GB + 6GB */ + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &ospi; + usb0 = &usb0; + rtc0 = &rtc; + }; +}; + +/* VADJ_FMC_EN - LPD MIO23 */ +/* FAN - LPD MIO21/22 */ +/* VCC_PL_EN - LPD MIO20 */ +/* PCIE_PERST - LPD MIO18/19 */ +/* SD_BUSPWR - PMC MIO51 */ +/* PCIE_WAKE - PMC MIO50 */ +/* VCCPSLP_EN - PMC MIO49 */ +/* I2C SYSMON - PMC MIO39 - 41 */ +/* PCIE_PWRBRK - PMC MIO38 */ +/* ZU4_TRIGGER - PMC MIO37 */ +/* VCC_AUX_1V2 - MIO11 */ + +&ospi { /* PMC MIO0-10, 12, U297 MT35XU02G */ + status = "okay"; + bus-num = <2>; + num-cs = <1>; + #stream-id-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + cdns,read-delay = <0>; + cdns,tshsl-ns = <0>; + cdns,tsd2d-ns = <0>; + cdns,tchsh-ns = <1>; + cdns,tslch-ns = <1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO13_500 - PMC_MIO25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO26-36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; +}; + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&gem0 { /* PMC_MIO_48, LPD_MIO0-11/24/25 */ + status = "okay"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: ethernet-phy@1 { /* u198 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&gpio1 48 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vek280-revB.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vek280-revB.dts @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal VEK280 revB + * + * (C) Copyright 2022, Advanced Micro Devices, Inc + * + * Michal Simek + */ + +#include +#include +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + compatible = "xlnx,versal-vek280-revB", "xlnx,versal-vek280", + "xlnx,versal"; + model = "Xilinx Versal vek280 Eval board revB"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x00000000 0x1 0x80000000>; /* 2GB + 6GB */ + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &ospi; + usb0 = &usb0; + rtc0 = &rtc; + nvmem0 = &eeprom; + }; +}; + +/* VADJ_FMC_EN - LPD MIO23 */ +/* FAN - LPD MIO21/22 */ +/* VCC_PL_EN - LPD MIO20 */ +/* PCIE_PERST - LPD MIO18/19 */ +/* SD_BUSPWR - PMC MIO51 */ +/* PCIE_WAKE - PMC MIO50 */ +/* VCCPSLP_EN - PMC MIO49 */ +/* I2C SYSMON - PMC MIO39 - 41 */ +/* PCIE_PWRBRK - PMC MIO38 */ +/* ZU4_TRIGGER - PMC MIO37 */ +/* VCC_AUX_1V2 - MIO11 */ + +&can0 { + status = "okay"; +}; + +&ospi { /* PMC MIO0-10, 12, U297 MT35XU02G */ + status = "okay"; + bus-num = <2>; + num-cs = <1>; + #stream-id-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + cdns,read-delay = <0>; + cdns,tshsl-ns = <0>; + cdns,tsd2d-ns = <0>; + cdns,tchsh-ns = <1>; + cdns,tslch-ns = <1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO13_500 - PMC_MIO25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO26-36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; +}; + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; + bootph-all; + clock-frequency = <100000>; + + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* & 0x5c */ + bootph-all; + }; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&gem0 { /* PMC_MIO_48, LPD_MIO0-11/24/25 */ + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@1 { /* u198 - ADI1300 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id0283.bc30"; + reg = <1>; + adi,rx-internal-delay-ps = <2000>; + adi,tx-internal-delay-ps = <2000>; + adi,fifo-depth-bits = <8>; + reset-gpios = <&gpio1 48 GPIO_ACTIVE_LOW>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; + }; + }; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vhk158-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vhk158-revA.dts @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal VHK158 revA + * + * (C) Copyright 2022, Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + compatible = "xlnx,versal-vhk158-revA", "xlnx,versal-vhk158", + "xlnx,versal"; + model = "Xilinx Versal vhk158 Eval board revA"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x7 0x80000000>; /* 32GB */ + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &ospi; + usb0 = &usb0; + rtc0 = &rtc; + }; +}; + +/* ZU4_TRIGGER - PMC MIO37 */ +/* PCIE_PWRBRK - PMC MIO38 */ +/* I2C SYSMON - PMC MIO39 - 41 */ +/* VCCPSLP_EN - PMC MIO49 */ +/* PCIE_WAKE - PMC MIO50 */ +/* SOC_EN - LPD MIO13 */ +/* PSFP_EN - LPD MIO15 */ +/* AUX_1V2_EN - LPD MIO16 */ +/* HBM_EN - LPD MIO17 */ +/* PCIE_PERST - LPD MIO18/19 */ +/* VCC_PL_EN - LPD MIO20 */ +/* FAN - LPD MIO21/22 */ +/* VADJ_FMC_EN - LPD MIO23 */ + +&ospi { /* PMC MIO0 - 12, U297 MT35XU02G */ + status = "okay"; + bus-num = <2>; + num-cs = <1>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + cdns,read-delay = <0>; + cdns,tshsl-ns = <0>; + cdns,tsd2d-ns = <0>; + cdns,tchsh-ns = <1>; + cdns,tslch-ns = <1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO13_500 - PMC_MIO25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO26-36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; +}; + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&gem0 { /* PMC_MIO_48, LPD_MIO0-11/24/25 */ + status = "okay"; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: ethernet-phy@1 { /* u198 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&gpio1 48 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1-x-ebm-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1-x-ebm-01-revA.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 rev1.1 with X-EBM-01-revA module + * + * (C) Copyright 2019 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1.dts" + +/ { + compatible = "xlnx,versal-vmk180-rev1.1-x-ebm-01-revA", + "xlnx,versal-vmk180-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board rev1.1 (QSPI)"; +}; + +&qspi { +#include "versal-x-ebm-01-revA.dtsi" +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1-x-ebm-02-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1-x-ebm-02-revA.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 rev1.1 with X-EBM-02-revA module + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1.dts" + +/ { + compatible = "xlnx,versal-vmk180-rev1.1-x-ebm-02-revA", + "xlnx,versal-vmk180-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board rev1.1 (EMMC)"; +}; + +&sdhci1 { +#include "versal-x-ebm-02-revA.dtsi" +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1-x-ebm-03-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1-x-ebm-03-revA.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 rev1.1 with X-EBM-03-revA module + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-rev1.1.dts" + +/ { + compatible = "xlnx,versal-vmk180-rev1.1-x-ebm-03-revA", + "xlnx,versal-vmk180-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board rev1.1 (OSPI)"; +}; + +&ospi { +#include "versal-x-ebm-03-revA.dtsi" +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-rev1.1.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 rev1.1 + * + * (C) Copyright 2019 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA.dts" + +/ { + compatible = "xlnx,versal-vmk180-rev1.1", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board rev1.1"; +}; + +&sdhci1 { /* PMC_MIO26-36/51 */ + clk-phase-sd-hs = <111>, <48>; + clk-phase-uhs-sdr25 = <114>, <48>; + clk-phase-uhs-ddr50 = <126>, <36>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-revA-x-ebm-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-revA-x-ebm-01-revA.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 revA with X-EBM-01-revA module + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA.dts" + +/ { + compatible = "xlnx,versal-vmk180-revA-x-ebm-01-revA", + "xlnx,versal-vmk180-revA", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board revA (QSPI)"; +}; + +&qspi { +#include "versal-x-ebm-01-revA.dtsi" +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-revA-x-ebm-02-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-revA-x-ebm-02-revA.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 revA with X-EBM-02-revA module + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA.dts" + +/ { + compatible = "xlnx,versal-vmk180-revA-x-ebm-02-revA", + "xlnx,versal-vmk180-revA", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board revA (EMMC)"; +}; + +&sdhci1 { +#include "versal-x-ebm-02-revA.dtsi" +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-revA-x-ebm-03-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-revA-x-ebm-03-revA.dts @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 revA with X-EBM-03-revA module + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal-vmk180-revA.dts" + +/ { + compatible = "xlnx,versal-vmk180-revA-x-ebm-03-revA", + "xlnx,versal-vmk180-revA", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board revA (OSPI)"; + + aliases { + spi0 = &ospi; + }; +}; + +&ospi { +#include "versal-x-ebm-03-revA.dtsi" +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vmk180-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vmk180-revA.dts @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vmk180 revA + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + compatible = "xlnx,versal-vmk180-revA", "xlnx,versal"; + model = "Xilinx Versal vmk180 Eval board revA"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x1 0x80000000>; + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + ethernet0 = &gem0; + ethernet1 = &gem1; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + rtc0 = &rtc; + }; +}; + +/* PMC_MIO 0 -12 - configuration header QSPI/OSPI/EMMC */ +/* FIXME PMC_MIO37 ZU4_TRIGGER/PMC_MIO37/38 PCIE */ + +&can1 { /* MIO40-41 */ + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&sdhci1 { /* PMC_MIO26-36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; +}; + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&gem0 { /* PMC_MIO_48, LPD_MIO0-11/24/25 */ + status = "okay"; + phy-handle = <&phy1>; /* u198 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy1: ethernet-phy@1 { /* u198 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&gpio1 48 GPIO_ACTIVE_LOW>; + }; + phy2: ethernet-phy@2 { /* u134 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <2>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&gpio1 49 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gem1 { /* PMC_MIO_49, LPD_MIO12-23 */ + status = "okay"; + phy-handle = <&phy2>; /* u134 */ + phy-mode = "rgmii-id"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; +}; + +&usb0 { /* PMC_MIO13_500 - PMC_MIO25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vp-x-a2785-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vp-x-a2785-00-revA.dts @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vp-x-a2785-00 revA + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + model = "Xilinx Versal vp-x-a2785-00 Eval board revA"; + compatible = "xlnx,versal-vp-x-a2785-00-revA", + "xlnx,versal-vp-x-a2785-00", "xlnx,versal"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x1 0x80000000>; + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + rtc0 = &rtc; + }; + /* Missing any LED for heartbeat */ +}; + +&qspi { /* PMC_MIO_500 0 - 12 */ + status = "okay"; /* u93 and u92 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <35000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO_500 13 - 25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; /* FIXME */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO_501 26 - 36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; +}; + +/* PWM via MIO 41/FAN TACH MIO 49 - FIXME */ + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; +}; + +/* PCIe at MIO 38/39/40/50 */ + +&gem0 { /* PMC_MIO_48 - reset, LPD_MIO0-11 , mdio LPD_MIO24/25 */ + status = "okay"; + phy-handle = <&phy1>; /* u198 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + }; + }; +}; + +/* LPD_MIO12-23 - PM */ + +&can1 { /* MIO40-41 */ + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&gpio1 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&watchdog { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vpk120-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vpk120-revA.dts @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vpk120 revA + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + model = "Xilinx Versal vpk120 Eval board revA"; + compatible = "xlnx,versal-vpk120-revA", "xlnx,versal-vpk120", + "xlnx,versal"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x2 0x80000000>; + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + rtc0 = &rtc; + }; + /* Missing any LED for heartbeat */ +}; + +&qspi { /* PMC_MIO_500 0 - 12 */ + status = "okay"; /* u93 and u92 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <35000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO_500 13 - 25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; /* FIXME */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO_501 26 - 36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; +}; + +/* PWM via MIO 41/FAN TACH MIO 49 - FIXME */ + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; +}; + +/* PCIe at MIO 38/39/40/50 */ + +&gem0 { /* PMC_MIO_48 - reset, LPD_MIO0-11 , mdio LPD_MIO24/25 */ + status = "okay"; + phy-handle = <&phy1>; /* u198 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + }; + }; +}; + +/* LPD_MIO12-23 - PM */ + +&can1 { /* MIO40-41 */ + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&gpio1 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&watchdog { + status = "okay"; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vpk120-revB.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vpk120-revB.dts @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vpk120 revB + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + model = "Xilinx Versal vpk120 Eval board revB"; + compatible = "xlnx,versal-vpk120-revB", "xlnx,versal-vpk120", + "xlnx,versal"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x2 0x80000000>; + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + rtc0 = &rtc; + }; + /* Missing any LED for heartbeat */ +}; + +&qspi { /* PMC_MIO_500 0 - 12 */ + status = "okay"; /* u93 and u92 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <35000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO_500 13 - 25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; /* FIXME */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO_501 26 - 36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; + clk-phase-sd-hs = <111>, <48>; + clk-phase-uhs-sdr25 = <114>, <48>; + clk-phase-uhs-ddr50 = <126>, <36>; +}; + +/* PWM via MIO 41/FAN TACH MIO 49 - FIXME */ + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; + + /* Use for storing information about board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* & 0x5c */ + bootph-all; + }; +}; + +/* PCIe at MIO 38/39/40/50 */ + +&gem0 { /* PMC_MIO_48 - reset, LPD_MIO0-11 , mdio LPD_MIO24/25 */ + status = "okay"; + phy-handle = <&phy1>; /* u198 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + }; + }; +}; + +/* LPD_MIO12-23 - PM */ + +&can1 { /* MIO40-41 */ + status = "okay"; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&gpio1 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&watchdog { + status = "okay"; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-vpk180-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-vpk180-revA.dts @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal vpk180 revA + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include "versal.dtsi" +#include "versal-clk.dtsi" + +/ { + model = "Xilinx Versal vpk180 Eval board revA"; + compatible = "xlnx,versal-vpk180-revA", "xlnx,versal-vpk180", + "xlnx,versal"; + + memory: memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x2 0x80000000>; + }; + + chosen { + bootargs = "console=ttyAMA0 earlycon=pl011,mmio32,0xFF000000,115200n8"; + stdout-path = "serial0:115200"; + }; + + aliases { + serial0 = &serial0; + serial2 = &dcc; + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + spi0 = &qspi; + usb0 = &usb0; + rtc0 = &rtc; + }; + /* Missing any LED for heartbeat */ +}; + +&qspi { /* PMC_MIO_500 0 - 12 */ + status = "okay"; /* u93 and u92 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <35000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; + }; +}; + +&usb0 { /* PMC_MIO_500 13 - 25 USB 2.0 */ + status = "okay"; +}; + +&dwc3_0 { /* USB 2.0 host */ + status = "okay"; + dr_mode = "host"; + maximum-speed = "high-speed"; /* FIXME */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,usb3_lpm_capable; +}; + +&sdhci1 { /* PMC_MIO_501 26 - 36/51 */ + status = "okay"; + xlnx,mio-bank = <1>; + no-1-8-v; + clk-phase-sd-hs = <111>, <48>; + clk-phase-uhs-sdr25 = <114>, <48>; + clk-phase-uhs-ddr50 = <126>, <36>; +}; + +&serial0 { /* PMC_MIO42/43 */ + status = "okay"; +}; + +&i2c0 { /* PMC_MIO46/47 */ + status = "okay"; +}; + +&i2c1 { /* PMC_MIO44/45 */ + status = "okay"; + + /* Use for storing information about board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* & 0x5c */ + bootph-all; + }; +}; + +&gem0 { /* PMC_MIO_48 - reset, LPD_MIO0-11 , mdio LPD_MIO24/25 */ + status = "okay"; + phy-handle = <&phy1>; /* u198 */ + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0xb>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <1>; + ti,dp83867-rxctrl-strap-quirk; + }; + }; +}; + +&dcc { + status = "okay"; +}; + +&rtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&gpio1 { + status = "okay"; + /* FIXME Fill names when versal starts */ +}; + +&watchdog { + status = "okay"; +}; + +&lpd_dma_chan0 { + status = "okay"; +}; + +&lpd_dma_chan1 { + status = "okay"; +}; + +&lpd_dma_chan2 { + status = "okay"; +}; + +&lpd_dma_chan3 { + status = "okay"; +}; + +&lpd_dma_chan4 { + status = "okay"; +}; + +&lpd_dma_chan5 { + status = "okay"; +}; + +&lpd_dma_chan6 { + status = "okay"; +}; + +&lpd_dma_chan7 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-x-ebm-01-revA.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-x-ebm-01-revA.dtsi @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx X-EBM-01 revA for vck190/vmk180 + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +status = "okay"; +num-cs = <2>; +spi-tx-bus-width = <4>; +spi-rx-bus-width = <4>; +#address-cells = <1>; +#size-cells = <0>; +flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "m25p80", "jedec,spi-nor"; /* 256MB */ + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <150000000>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x10000000>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-x-ebm-01-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-x-ebm-01-revA.dtso @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx X-EBM-01 revA for vck190/vmk180 + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,versal-x-ebm-01-revA", "xlnx,versal-x-ebm-01"; + + fragment { + target = <&qspi>; + + __overlay__ { +#include "versal-x-ebm-01-revA.dtsi" + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-x-ebm-02-revA.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-x-ebm-02-revA.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx X-EBM-02 revA for vck190/vmk180 + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +/* emmc MIO 0-13 - MTFC8GAKAJCN */ +status = "okay"; +non-removable; +disable-wp; +no-sd; +no-sdio; +cap-mmc-hw-reset; +bus-width = <8>; +xlnx,mio-bank = <0>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-x-ebm-02-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-x-ebm-02-revA.dtso @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx X-EBM-02 revA for vck190/vmk180 + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,versal-x-ebm-02-revA", "xlnx,versal-x-ebm-02"; + + fragment { + target = <&sdhci1>; + + __overlay__ { +#include "versal-x-ebm-02-revA.dtsi" + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-x-ebm-03-revA.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-x-ebm-03-revA.dtsi @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx X-EBM-03 revA for vck190/vmk180 + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include + +/* U97 MT35XU02G */ +status = "okay"; +bus-num = <2>; +num-cs = <1>; +#address-cells = <1>; +#size-cells = <0>; + +flash@0 { + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + cdns,read-delay = <0x0>; + cdns,tshsl-ns = <0x0>; + cdns,tsd2d-ns = <0x0>; + cdns,tchsh-ns = <0x1>; + cdns,tslch-ns = <0x1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; + reset-gpios = <&gpio1 0xc GPIO_ACTIVE_LOW>; + partition@0 { + label = "spi0-flash0"; + reg = <0x0 0x8000000>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal-x-ebm-03-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal-x-ebm-03-revA.dtso @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx X-EBM-03 revA for vck190/vmk180 + * + * (C) Copyright 2020, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,versal-x-ebm-03-revA", "xlnx,versal-x-ebm-03"; + + fragment { + target = <&ospi>; + + __overlay__ { +#include "versal-x-ebm-03-revA.dtsi" + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/versal.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/versal.dtsi @@ -0,0 +1,722 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal + * + * (C) Copyright 2017 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +/ { + compatible = "xlnx,versal"; + #address-cells = <2>; + #size-cells = <2>; + model = "Xilinx Versal"; + + options { + u-boot { + compatible = "u-boot,config"; + bootscr-address = /bits/ 64 <0x20000000>; + }; + }; + + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table>; + reg = <0>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + + cpu1: cpu@1 { + compatible = "arm,cortex-a72"; + device_type = "cpu"; + enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table>; + reg = <1>; + cpu-idle-states = <&CPU_SLEEP_0>; + }; + + idle-states { + entry-method = "psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x40000000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <600>; + min-residency-us = <10000>; + }; + }; + }; + + cpu_opp_table: opp-table-cpu { + compatible = "operating-points-v2"; + opp-shared; + opp00 { + opp-hz = /bits/ 64 <1199999988>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp01 { + opp-hz = /bits/ 64 <599999994>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp02 { + opp-hz = /bits/ 64 <399999996>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp03 { + opp-hz = /bits/ 64 <299999997>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; + bootph-all; + }; + + fpga: fpga-region { + compatible = "fpga-region"; + fpga-mgr = <&versal_fpga>; + #address-cells = <2>; + #size-cells = <2>; + }; + + psci: psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupt-parent = <&gic>; + interrupts = <1 7 0x304>; + }; + + timer: timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = <1 13 4>, + <1 14 4>, + <1 11 4>, + <1 10 4>; + }; + + versal_fpga: versal-fpga { + compatible = "xlnx,versal-fpga"; + }; + + sensor0: versal-thermal-sensor { + compatible = "xlnx,versal-thermal"; + #thermal-sensor-cells = <0>; + io-channels = <&sysmon0>; + io-channel-names = "sysmon-temp-channel"; + }; + + thermal-zones { + versal_thermal: versal-thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + thermal-sensors = <&sensor0>; + + trips { + temp_alert: temp-alert { + temperature = <70000>; /* millicelsius */ + hysteresis = <0>; /* millicelsius */ + type = "passive"; + }; + + ot_crit: ot-crit { + temperature = <125000>; /* millicelsius */ + hysteresis = <0>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + }; + }; + }; + + amba: axi { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-parent = <&gic>; + bootph-all; + + gic: interrupt-controller@f9000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0 0xf9000000 0 0x80000>, /* GICD */ + <0 0xf9080000 0 0x80000>; /* GICR */ + interrupt-controller; + interrupts = <1 9 4>; + + gic_its: msi-controller@f9020000 { + compatible = "arm,gic-v3-its"; + status = "disabled"; + msi-controller; + #msi-cells = <1>; + reg = <0 0xf9020000 0 0x20000>; + }; + }; + + can0: can@ff060000 { + compatible = "xlnx,canfd-2.0"; + status = "disabled"; + reg = <0 0xff060000 0 0x6000>; + interrupts = <0 20 4>; + clock-names = "can_clk", "s_axi_aclk"; + rx-fifo-depth = <0x40>; + tx-mailbox-count = <0x20>; + }; + + can1: can@ff070000 { + compatible = "xlnx,canfd-2.0"; + status = "disabled"; + reg = <0 0xff070000 0 0x6000>; + interrupts = <0 21 4>; + clock-names = "can_clk", "s_axi_aclk"; + rx-fifo-depth = <0x40>; + tx-mailbox-count = <0x20>; + }; + + cci: cci@fd000000 { + compatible = "arm,cci-500"; + status = "disabled"; + reg = <0 0xfd000000 0 0x10000>; + ranges = <0 0 0xfd000000 0xa0000>; + #address-cells = <1>; + #size-cells = <1>; + cci_pmu: pmu@10000 { + compatible = "arm,cci-500-pmu,r0"; + reg = <0x10000 0x90000>; + interrupts = <0 106 4>, + <0 106 4>, + <0 106 4>, + <0 106 4>, + <0 106 4>, + <0 106 4>, + <0 106 4>, + <0 106 4>; + }; + }; + + lpd_dma_chan0: dma-controller@ffa80000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffa80000 0 0x1000>; + interrupts = <0 60 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x210>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan1: dma-controller@ffa90000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffa90000 0 0x1000>; + interrupts = <0 61 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x212>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan2: dma-controller@ffaa0000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffaa0000 0 0x1000>; + interrupts = <0 62 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x214>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan3: dma-controller@ffab0000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffab0000 0 0x1000>; + interrupts = <0 63 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x216>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan4: dma-controller@ffac0000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffac0000 0 0x1000>; + interrupts = <0 64 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x218>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan5: dma-controller@ffad0000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffad0000 0 0x1000>; + interrupts = <0 65 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x21a>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan6: dma-controller@ffae0000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffae0000 0 0x1000>; + interrupts = <0 66 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x21c>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + lpd_dma_chan7: dma-controller@ffaf0000 { + compatible = "xlnx,zynqmp-dma-1.0"; + status = "disabled"; + reg = <0 0xffaf0000 0 0x1000>; + interrupts = <0 67 4>; + clock-names = "clk_main", "clk_apb"; + /* iommus = <&smmu 0x21e>; */ + #dma-cells = <1>; + xlnx,bus-width = <64>; + /* dma-coherent; */ + }; + + gem0: ethernet@ff0c0000 { + compatible = "xlnx,versal-gem", "cdns,gem"; + status = "disabled"; + reg = <0 0xff0c0000 0 0x1000>; + interrupts = <0 56 4>, <0 56 4>; + clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; + /* iommus = <&smmu 0x234>; */ + /* dma-coherent; */ + #address-cells = <1>; + #size-cells = <0>; + }; + + gem1: ethernet@ff0d0000 { + compatible = "xlnx,versal-gem", "cdns,gem"; + status = "disabled"; + reg = <0 0xff0d0000 0 0x1000>; + interrupts = <0 58 4>, <0 58 4>; + clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; + /* iommus = <&smmu 0x235>; */ + /* dma-coherent; */ + #address-cells = <1>; + #size-cells = <0>; + }; + + gpio0: gpio@ff0b0000 { + compatible = "xlnx,versal-gpio-1.0"; + status = "disabled"; + reg = <0 0xff0b0000 0 0x1000>; + interrupts = <0 13 4>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio1: gpio@f1020000 { + compatible = "xlnx,pmc-gpio-1.0"; + status = "disabled"; + reg = <0 0xf1020000 0 0x1000>; + interrupts = <0 122 4>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + }; + + i2c0: i2c@ff020000 { + compatible = "cdns,i2c-r1p14"; + status = "disabled"; + reg = <0 0xff020000 0 0x1000>; + interrupts = <0 14 4>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@ff030000 { + compatible = "cdns,i2c-r1p14"; + status = "disabled"; + reg = <0 0xff030000 0 0x1000>; + interrupts = <0 15 4>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@f1000000 { + compatible = "cdns,i2c-r1p14"; + status = "disabled"; + reg = <0 0xf1000000 0 0x1000>; + interrupts = <0 123 4>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mc0: memory-controller@f6150000 { + compatible = "xlnx,versal-ddrmc"; + status = "disabled"; + reg = <0x0 0xf6150000 0x0 0x2000>, <0x0 0xf6070000 0x0 0x20000>; + reg-names = "base", "noc"; + interrupts = <0 147 4>; + }; + + mc1: memory-controller@f62c0000 { + compatible = "xlnx,versal-ddrmc"; + status = "disabled"; + reg = <0x0 0xf62c0000 0x0 0x2000>, <0x0 0xf6210000 0x0 0x20000>; + reg-names = "base", "noc"; + interrupts = <0 147 4>; + }; + + mc2: memory-controller@f6430000 { + compatible = "xlnx,versal-ddrmc"; + status = "disabled"; + reg = <0x0 0xf6430000 0x0 0x2000>, <0x0 0xf6380000 0x0 0x20000>; + reg-names = "base", "noc"; + interrupts = <0 147 4>; + }; + + mc3: memory-controller@f65a0000 { + compatible = "xlnx,versal-ddrmc"; + status = "disabled"; + reg = <0x0 0xf65a0000 0x0 0x2000>, <0x0 0xf64f0000 0x0 0x20000>; + reg-names = "base", "noc"; + interrupts = <0 147 4>; + }; + + ocm: memory-controller@ff960000 { + compatible = "xlnx,zynqmp-ocmc-1.0"; + reg = <0x0 0xff960000 0x0 0x1000>; + interrupts = <0 10 4>; + }; + + rtc: rtc@f12a0000 { + compatible = "xlnx,zynqmp-rtc"; + status = "disabled"; + reg = <0 0xf12a0000 0 0x100>; + interrupt-names = "alarm", "sec"; + interrupts = <0 142 4>, <0 143 4>; + calibration = <0x7FFF>; + }; + + sdhci0: mmc@f1040000 { + compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; + status = "disabled"; + reg = <0 0xf1040000 0 0x10000>; + interrupts = <0 126 4>; + clock-names = "clk_xin", "clk_ahb", "gate"; + #clock-cells = <1>; + clock-output-names = "clk_out_sd0", "clk_in_sd0"; + /* iommus = <&smmu 0x242>; */ + /* dma-coherent; */ + }; + + sdhci1: mmc@f1050000 { + compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; + status = "disabled"; + reg = <0 0xf1050000 0 0x10000>; + interrupts = <0 128 4>; + clock-names = "clk_xin", "clk_ahb", "gate"; + #clock-cells = <1>; + clock-output-names = "clk_out_sd1", "clk_in_sd1"; + /* iommus = <&smmu 0x243>; */ + /* dma-coherent; */ + }; + + serial0: serial@ff000000 { + compatible = "arm,pl011", "arm,primecell"; + status = "disabled"; + reg = <0 0xff000000 0 0x1000>; + interrupts = <0 18 4>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + bootph-all; + }; + + serial1: serial@ff010000 { + compatible = "arm,pl011", "arm,primecell"; + status = "disabled"; + reg = <0 0xff010000 0 0x1000>; + interrupts = <0 19 4>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + bootph-all; + }; + + smmu: iommu@fd800000 { + compatible = "arm,mmu-500"; + status = "disabled"; + reg = <0 0xfd800000 0 0x40000>; + stream-match-mask = <0x7c00>; + #iommu-cells = <1>; + #global-interrupts = <1>; + interrupts = <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>, + <0 107 4>, <0 107 4>, <0 107 4>, <0 107 4>; + }; + + ospi: spi@f1010000 { + compatible = "xlnx,versal-ospi-1.0", "cdns,qspi-nor"; + status = "disabled"; + reg = <0 0xf1010000 0 0x10000 0 0xc0000000 0 0x20000000>; + interrupts = <0 124 4>; + cdns,fifo-depth = <256>; + cdns,fifo-width = <4>; + cdns,is-dma = <1>; + cdns,trigger-address = <0xC0000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + qspi: spi@f1030000 { + compatible = "xlnx,versal-qspi-1.0"; + status = "disabled"; + reg = <0 0xf1030000 0 0x1000>; + interrupts = <0 125 4>; + clock-names = "ref_clk", "pclk"; + /* iommus = <&smmu 0x244>; */ + /* dma-coherent; */ + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@ff040000 { + compatible = "cdns,spi-r1p6"; + status = "disabled"; + reg = <0 0xff040000 0 0x1000>; + interrupts = <0 16 4>; + clock-names = "ref_clk", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@ff050000 { + compatible = "cdns,spi-r1p6"; + status = "disabled"; + reg = <0 0xff050000 0 0x1000>; + interrupts = <0 17 4>; + clock-names = "ref_clk", "pclk"; + #address-cells = <1>; + #size-cells = <0>; + }; + + sysmon0: sysmon@f1270000 { + compatible = "xlnx,versal-sysmon"; + #io-channel-cells = <0>; + reg = <0x0 0xf1270000 0x0 0x4000>; + interrupts = <0 144 4>; + xlnx,numchannels = /bits/8 <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + sysmon1: sysmon@109270000 { + compatible = "xlnx,versal-sysmon"; + status = "disabled"; + reg = <0x1 0x09270000 0x0 0x4000>; + xlnx,numchannels = /bits/8 <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + sysmon2: sysmon@111270000 { + compatible = "xlnx,versal-sysmon"; + status = "disabled"; + reg = <0x1 0x11270000 0x0 0x4000>; + xlnx,numchannels = /bits/8 <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + sysmon3: sysmon@119270000 { + compatible = "xlnx,versal-sysmon"; + status = "disabled"; + reg = <0x1 0x19270000 0x0 0x4000>; + xlnx,numchannels = /bits/8 <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + ttc0: timer@ff0e0000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 37 4>, <0 38 4>, <0 39 4>; + reg = <0x0 0xff0e0000 0x0 0x1000>; + timer-width = <32>; + }; + + ttc1: timer@ff0f0000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 40 4>, <0 41 4>, <0 42 4>; + reg = <0x0 0xff0f0000 0x0 0x1000>; + timer-width = <32>; + }; + + ttc2: timer@ff100000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 43 4>, <0 44 4>, <0 45 4>; + reg = <0x0 0xff100000 0x0 0x1000>; + timer-width = <32>; + }; + + ttc3: timer@ff110000 { + compatible = "cdns,ttc"; + status = "disabled"; + interrupts = <0 46 4>, <0 47 4>, <0 48 4>; + reg = <0x0 0xff110000 0x0 0x1000>; + timer-width = <32>; + }; + + usb0: usb@ff9d0000 { + compatible = "xlnx,versal-dwc3"; + status = "disabled"; + reg = <0 0xff9d0000 0 0x100>; + clock-names = "bus_clk", "ref_clk"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + + dwc3_0: usb@fe200000 { + compatible = "snps,dwc3"; + status = "disabled"; + reg = <0 0xfe200000 0 0x10000>; + interrupt-names = "host", "peripheral", "otg", "wakeup"; + interrupts = <0 0x16 4>, <0 0x16 4>, <0 0x1a 4>, <0x0 0x4a 0x4>; + /* iommus = <&smmu 0x230>; */ + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,quirk-frame-length-adjustment = <0x20>; + clock-names = "ref"; + /* dma-coherent; */ + }; + }; + + cpm_pciea: pci@fca10000 { + device_type = "pci"; + #address-cells = <3>; + #interrupt-cells = <1>; + #size-cells = <2>; + compatible = "xlnx,versal-cpm-host-1.00"; + status = "disabled"; + interrupt-map = <0 0 0 1 &pcie_intc_0 0>, + <0 0 0 2 &pcie_intc_0 1>, + <0 0 0 3 &pcie_intc_0 2>, + <0 0 0 4 &pcie_intc_0 3>; + interrupt-map-mask = <0 0 0 7>; + interrupt-names = "misc"; + interrupts = <0 72 4>; + interrupt-parent = <&gic>; + bus-range = <0x00 0xff>; + ranges = <0x02000000 0x00000000 0xe0010000 0x0 0xe0010000 0x00000000 0x10000000>, + <0x43000000 0x00000080 0x00000000 0x00000080 0x00000000 0x00000000 0x80000000>; + msi-map = <0x0 &gic_its 0x0 0x10000>; + reg = <0x0 0xfca10000 0x0 0x1000>, + <0x6 0x00000000 0x0 0x1000000>; + reg-names = "cpm_slcr", "cfg"; + pcie_intc_0: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller ; + }; + }; + + cpm5_pcie: pcie@fcdd0000 { + device_type = "pci"; + #address-cells = <3>; + #interrupt-cells = <1>; + #size-cells = <2>; + compatible = "xlnx,versal-cpm5-host"; + status = "disabled"; + interrupt-map = <0 0 0 1 &pcie_intc_1 0>, + <0 0 0 2 &pcie_intc_1 1>, + <0 0 0 3 &pcie_intc_1 2>, + <0 0 0 4 &pcie_intc_1 3>; + interrupt-map-mask = <0 0 0 7>; + interrupt-names = "misc"; + interrupts = <0 72 4>; + interrupt-parent = <&gic>; + bus-range = <0x00 0xff>; + ranges = <0x02000000 0x0 0xe0000000 0x0 0xe0000000 0x0 0x10000000>, + <0x43000000 0x80 0x00000000 0x80 0x00000000 0x0 0x80000000>; + msi-map = <0x0 &gic_its 0x0 0x10000>; + reg = <0x00 0xfcdd0000 0x00 0x1000>, + <0x06 0x00000000 0x00 0x1000000>, + <0x00 0xfce20000 0x00 0x1000000>; + reg-names = "cpm_slcr", "cfg", "cpm_csr"; + pcie_intc_1: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + + watchdog: watchdog@fd4d0000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xfd4d0000 0 0x10000>; + timeout-sec = <30>; + }; + + watchdog1: watchdog@ff120000 { + compatible = "xlnx,versal-wwdt"; + status = "disabled"; + reg = <0 0xff120000 0 0x10000>; + timeout-sec = <30>; + }; + + xilsem_edac: edac@f2014050 { + compatible = "xlnx,versal-xilsem-edac"; + status = "disabled"; + reg = <0x0 0xf2014050 0x0 0xc4>; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/x-prc-07-i3c-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/x-prc-07-i3c-revA.dtso @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197 (Tenzing2) X-PRC-07 RevA with I3C enabled + * + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Jay Buddhabhatti ; + */ + +#include "x-prc-07-revA.dtso" + +&{/} { + model = "X-PRC-07 i3c revA"; +}; + +&i2c0 { + status = "disabled"; +}; + +&i2c1 { + status = "disabled"; +}; + +&i3c0 { + status = "okay"; + #address-cells = <3>; + #size-cells = <0>; + + /* check maximum frequency from datasheet */ + imu@6b { /* u120 */ + compatible = "st,lsm6dso"; + reg = <0 0 0x6b>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/x-prc-07-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/x-prc-07-revA.dtso @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197 (Tenzing2) X-PRC-07 RevA + * + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + model = "X-PRC-07 revA"; + + aliases { + nvmem2 = &eeprom0; + nvmem3 = &eeprom1; + }; +}; + +&gem1 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rmii"; + mdio1: mdio { + #address-cells = <1>; + #size-cells = <0>; + + /* u393 DP83867 - DNP */ + /* + phy0: ethernet-phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&gpio1 22 GPIO_ACTIVE_LOW>; + }; + */ + /* phy also respond on broadcast address 0 */ + phy0: ethernet-phy@1 { /* u396 RTL8201F */ + #phy-cells = <1>; + compatible = "ethernet-phy-id001c.c816"; + reg = <1>; + }; + }; +}; + +&ospi { + status = "okay"; + num-cs = <2>; + reset-names = "qspi"; + #address-cells = <1>; + #size-cells = <0>; + + mt35xu02g: flash@0 { /* u97/u390 mt35xu02gcba */ + compatible = "mt35xu02g", "micron,m25p80", "jedec,spi-nor"; + reg = <0>, <1>; + stacked-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + #address-cells = <1>; + #size-cells = <1>; + cdns,read-delay = <0>; + cdns,tshsl-ns = <0>; + cdns,tsd2d-ns = <0>; + cdns,tchsh-ns = <1>; + cdns,tslch-ns = <1>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + broken-flash-reset; + no-wp; + reset-gpios = <&gpio1 0xc GPIO_ACTIVE_LOW>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "ospi-flash0"; + reg = <0 0x200000>; + }; + partition@1 { + label = "ospi-flash1"; + reg = <0x200000 0x7E00000>; + }; + }; + }; +}; + +&spi1 { + status = "okay"; + num-cs = <3>; + #address-cells = <1>; + #size-cells = <0>; + + flash@2 { /* u397 MX25U3232 - FIXME not supported in U-Boot/Linux */ + compatible = "m25p80", "jedec,spi-nor"; + spi-max-frequency = <5000000>; + reg = <2>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "spi0-flash0"; + reg = <0 0x80000>; + }; + }; + }; +}; + +&i2c0 { + status = "okay"; + bootph-all; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom0: eeprom@51 { /* u45 WP not used */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + bootph-all; + }; +}; + +&i2c1 { + status = "okay"; + bootph-all; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom1: eeprom@51 { /* u46 WP not used */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + bootph-all; + }; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; + xlnx,mio-bank = <0>; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; +}; + +&usb1 { + status = "okay"; +}; + +&dwc3_1 { + status = "okay"; + snps,ulpi-ext-vbus-drv; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/x-prc-08-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/x-prc-08-revA.dtso @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197 (Tenzing2) X-PRC-08 RevA + * + * (C) Copyright 2022-2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + model = "X-PRC-08 revA"; +}; + +/* LPD_MIO0-12, mdio LPD_MIO24-25 */ +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rmii"; + mdio1: mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@1 { /* u37 VSC8540 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id0007.0760"; + reg = <1>; + reset-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* u1, u2, u3, u4 - 4x MT25QU01GBBBB, PMC_MIO0-5,7-12 */ +&qspi { + status = "okay"; + reset-gpios = <&gpio1 39 GPIO_ACTIVE_HIGH>; + reset-names = "qspi"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <2>; + + mt25xu01g: flash@0 { + compatible = "micron,m25p80", "jedec,spi-nor"; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* (128+128)MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <150000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "qspi-flash0"; + reg = <0 0x8000000>; + }; + partition@1 { + label = "qspi-flash1"; + reg = <0x8000000 0x8000000>; + }; + }; + }; +}; + +/* LPD_MIO18-23 */ +&spi1 { + status = "okay"; + num-cs = <1>; /* Via J16 - 3 chip selects to the same memory */ + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { /* u35 MX25U3232 */ + compatible = "m25p80"; + spi-max-frequency = <5000000>; + reg = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "spi0-flash0"; + reg = <0 0x80000>; + }; + }; + }; +}; + +/* LPD_MIO16-17 */ +&serial0 { + status = "okay"; +}; + +/* PMC_MIO26-36 */ +&sdhci0 { + status = "okay"; + xlnx,mio-bank = <1>; + bus-width = <4>; +}; + +/* u36a PMC_MIO40-51 MTFC16GAPALBH */ +&sdhci1 { + status = "okay"; + xlnx,mio-bank = <1>; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; +}; + +/* u34 - usb3315c - PMC_MIO13-25 */ +&usb1 { + status = "okay"; +}; + +&dwc3_1 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/x-prc-09-i3c-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/x-prc-09-i3c-revA.dtso @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197 (Tenzing2) X-PRC-09 RevA with I3C enabled + * + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Jay Buddhabhatti ; + */ + +#include "x-prc-09-revA.dtso" + +&{/} { + model = "X-PRC-09 i3c revA"; +}; + +&i2c0 { + status = "disabled"; +}; + +&i2c1 { + status = "disabled"; +}; + +&i3c0 { + status = "okay"; + #address-cells = <3>; + #size-cells = <0>; + + /* check maximum frequency from datasheet */ + imu@6b { /* u120 */ + compatible = "st,lsm6dso"; + reg = <0 0 0x6b>; + }; +}; + +&i3c1 { /* u119 */ + status = "okay"; + #address-cells = <3>; + #size-cells = <0>; + + /* icm-42605 - missing i3c driver + drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c */ + icm42605@68 { + compatible = "invensense,icm42605"; + reg = <0 0 0x68>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/x-prc-09-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/x-prc-09-revA.dtso @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197 (Tenzing2) X-PRC-09 RevA + * + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +#include + +&{/} { + model = "X-PRC-09 revA"; + + aliases { + nvmem2 = &eeprom0; + nvmem3 = &eeprom1; + }; +}; + +&can0 { + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@1 { /* u128 DP83867 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + ti,min-output-impedance; + reset-assert-us = <0x96>; + reset-deassert-us = <0x118>; + reset-gpios = <&gpio1 48 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c0 { + status = "okay"; + bootph-all; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom0: eeprom@51 { /* u45 WP not used */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x51>; + bootph-all; + }; +}; + +&i2c1 { + status = "okay"; + bootph-all; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + eeprom1: eeprom@55 { /* u46 WP not used */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x55>; + bootph-all; + }; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&sdhci0 { + status = "okay"; + xlnx,mio-bank = <0>; + no-1-8-v; +}; + +&qspi { + status = "okay"; /* u93 and u92 */ + num-cs = <2>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "micron,m25p80", "jedec,spi-nor"; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x8000000 0x8000000>; /* 128MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <150000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "qspi0-flash0"; + reg = <0 0x200000>; + }; + partition@1 { + label = "qspi0-flash1"; + reg = <0x200000 0x7E00000>; + }; + }; + }; +}; + +&usb1 { + status = "okay"; +}; + +&dwc3_1 { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-a2197-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-a2197-revA.dts @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include + +/ { + model = "Versal System Controller on a2197 board RevA"; + compatible = "xlnx,zynqmp-a2197-revA", "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + i2c0 = &i2c0; + nvmem0 = &eeprom1; + nvmem1 = &eeprom0; + serial0 = &uart0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&i2c0 { + status = "okay"; + bootph-all; + clock-frequency = <400000>; + i2c-mux@74 { /* this cover MGT board */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + bootph-all; + /* FIXME reset connected to SYSCTRL_IIC_MUX0_RESET */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom0: eeprom@50 { /* u96 - 24LC32A - 256B */ + compatible = "atmel,24c32"; + bootph-all; + reg = <0x50>; + }; + }; + }; +}; + +&i2c1 { + status = "okay"; + bootph-all; + clock-frequency = <400000>; + i2c-mux@74 { /* This cover processor board */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + bootph-all; + /* FIXME reset connected to SYSCTRL_IIC_MUX0_RESET */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom1: eeprom@50 { /* u96 - 24LC32A - 256B */ + compatible = "atmel,24c32"; + bootph-all; + reg = <0x50>; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi @@ -182,6 +182,22 @@ clocks = <&zynqmp_clk I2C1_REF>; }; +&perf_monitor_ocm { + clocks = <&zynqmp_clk LPD_LSBUS>; +}; + +&perf_monitor_ddr { + clocks = <&zynqmp_clk TOPSW_LSBUS>; +}; + +&perf_monitor_cci { + clocks = <&zynqmp_clk TOPSW_LSBUS>; +}; + +&perf_monitor_lpd { + clocks = <&zynqmp_clk LPD_LSBUS>; +}; + &pcie { clocks = <&zynqmp_clk PCIE_REF>; }; @@ -230,18 +246,30 @@ &uart0 { clocks = <&zynqmp_clk UART0_REF>, <&zynqmp_clk LPD_LSBUS>; + assigned-clocks = <&zynqmp_clk UART0_REF>; }; &uart1 { clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>; + assigned-clocks = <&zynqmp_clk UART1_REF>; }; -&dwc3_0 { +&usb0 { clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; + assigned-clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; }; -&dwc3_1 { +&dwc3_0 { + clocks = <&zynqmp_clk USB3_DUAL_REF>; +}; + +&usb1 { clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; + assigned-clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; +}; + +&dwc3_1 { + clocks = <&zynqmp_clk USB3_DUAL_REF>; }; &watchdog0 { @@ -269,3 +297,7 @@ <&zynqmp_clk DP_AUDIO_REF>, <&zynqmp_clk DP_VIDEO_REF>; /* rpll, rpll, vpll */ }; + +&zynqmp_dp_snd_codec0 { + clocks = <&zynqmp_clk DP_AUDIO_REF>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-dlc21-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-dlc21-revA.dts @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP DLC21 revA + * + * (C) Copyright 2019 - 2021, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include + +/ { + model = "Smartlynq+ DLC21 RevA"; + compatible = "xlnx,zynqmp-dlc21-revA", "xlnx,zynqmp-dlc21", + "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + gpio0 = &gpio; + i2c0 = &i2c0; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + rtc0 = &rtc; + serial0 = &uart0; + serial2 = &dcc; + usb0 = &usb0; + usb1 = &usb1; + spi0 = &spi0; + nvmem0 = &eeprom; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0 0x3 0x80000000>; + }; + + si5332_1: si5332-1 { /* clk0_sgmii - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + si5332_2: si5332-2 { /* clk1_usb - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; +}; + +&sdhci1 { /* sd1 MIO45-51 cd in place */ + status = "okay"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +&psgtr { + status = "okay"; + /* sgmii, usb3 */ + clocks = <&si5332_1>, <&si5332_2>; + clock-names = "ref0", "ref1"; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; + bootph-all; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; /* DTG generates this properly 1512 */ + is-internal-pcspma; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + /* reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; */ + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "", "", "", "", "", /* 0 - 4 */ + "", "", "", "", "", /* 5 - 9 */ + "", "", "", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "DISP_SCL", "DISP_DC_B", "DISP_RES_B", "DISP_CS_B", /* 25 - 29 */ + "", "DISP_SDI", "SYSTEM_RST_R_B", "", "I2C0_SCL", /* 30 - 34 */ + "I2C0_SDA", "", "", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "", "", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD_B", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "USB1_CLK", /* 60 - 64 */ + "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", /* 65 - 69 */ + "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", /* 70 - 74 */ + "USB1_DATA7", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "VCCO_500_RBIAS", "VCCO_501_RBIAS", "VCCO_502_RBIAS", "VCCO_500_RBIAS_LED", /* 95 - 99 */ + "VCCO_501_RBIAS_LED", "VCCO_502_RBIAS_LED", "SYSCTLR_VCCINT_EN", "SYSCTLR_VCC_IO_SOC_EN", "SYSCTLR_VCC_PMC_EN", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "SYSCTLR_VCCO_500_EN", "SYSCTLR_VCCO_501_EN", "SYSCTLR_VCCO_502_EN", "SYSCTLR_VCCO_503_EN", "SYSCTLR_VCC1V8_EN", /* 110 - 114 */ + "SYSCTLR_VCC3V3_EN", "SYSCTLR_VCC1V2_DDR4_EN", "SYSCTLR_VCC1V1_LP4_EN", "SYSCTLR_VDD1_1V8_LP4_EN", "SYSCTLR_VADJ_FMC_EN", /* 115 - 119 */ + "", "", "", "SYSCTLR_UTIL_1V13_EN", "SYSCTLR_UTIL_1V8_EN", /* 120 - 124 */ + "SYSCTLR_UTIL_2V5_EN", "", "", "", "", /* 125 - 129 */ + "", "", "SYSCTLR_USBC_SBU1", "SYSCTLR_USBC_SBU2", "", /* 130 - 134 */ + "", "SYSCTLR_MIC2005_EN_B", "SYSCTLR_MIC2005_FAULT_B", "SYSCTLR_TUSB320_INT_B", "SYSCTLR_TUSB320_ID", /* 135 - 139 */ + "", "", "SYSCTLR_ETH_RESET_B", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO34/35 */ + status = "okay"; + clock-frequency = <400000>; + + jtag_vref: mcp4725@62 { + compatible = "microchip,mcp4725"; + reg = <0x62>; + vref-millivolt = <3300>; + }; + + eeprom: eeprom@50 { /* u46 */ + compatible = "atmel,24c32"; + reg = <0x50>; + }; + /* u138 - TUSB320IRWBR - for USB-C */ +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "peripheral"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + maximum-speed = "super-speed"; + phy-names = "usb3-phy"; + phys = <&psgtr 1 PHY_TYPE_USB3 0 1>; +}; + +&usb1 { + status = "disabled"; /* Any unknown issue with USB-C */ +}; + +&dwc3_1 { + /delete-property/ phy-names ; + /delete-property/ phys ; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk ; + snps,dis_u3_susphy_quirk ; + status = "okay"; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; + +&spi0 { + status = "okay"; + is-decoded-cs = <0>; + num-cs = <1>; + bootph-all; + displayspi@0 { + compatible = "syncoam,seps525"; + bootph-all; + reg = <0>; + status = "okay"; + spi-max-frequency = <10000000>; + spi-cpol; + spi-cpha; + rotate = <0>; + fps = <50>; + buswidth = <8>; + txbuflen = <64000>; + reset-gpios = <&gpio 0x1c GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio 0x1b GPIO_ACTIVE_HIGH>; + debug = <0>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-e-a2197-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-e-a2197-00-revA.dts @@ -0,0 +1,684 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include + +/ { + model = "Versal System Controller on a2197 Eval board RevA"; /* VCK190/VMK180 */ + compatible = "xlnx,zynqmp-e-a2197-00-revA", "xlnx,zynqmp-a2197-revA", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + nvmem0 = &eeprom; + nvmem1 = &eeprom_ebm; + nvmem2 = &eeprom_fmc1; + nvmem3 = &eeprom_fmc2; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &dcc; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ref_clk: ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_ref_clk>; + }; + + si570_ddrdimm1_clk: si570-ddrdimm1-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_ddr_dimm1>; + }; + + si570_lpddr4_clk2: si570-lpddr4-clk2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_lpddr4clk2>; + }; + + si570_lpddr4_clk1: si570-lpddr4-clk1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_lpddr4clk1>; + }; + + si570_hsdp_clk: si570-hsdp-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_hsdp>; + }; + + si570_zsfp_clk: si570-zsfp-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_zsfp>; + }; + + si570_user1_clk: si570-user1-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_user1>; + }; + + si5332_1: si5332-1 { /* u142 - GEM0 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + ina226-vccint { + compatible = "iio-hwmon"; + io-channels = <&vccint 0>, <&vccint 1>, <&vccint 2>, <&vccint 3>; + }; + ina226-vcc-soc { + compatible = "iio-hwmon"; + io-channels = <&vcc_soc 0>, <&vcc_soc 1>, <&vcc_soc 2>, <&vcc_soc 3>; + }; + ina226-vcc-pmc { + compatible = "iio-hwmon"; + io-channels = <&vcc_pmc 0>, <&vcc_pmc 1>, <&vcc_pmc 2>, <&vcc_pmc 3>; + }; + ina226-vcc-ram { + compatible = "iio-hwmon"; + io-channels = <&vcc_ram 0>, <&vcc_ram 1>, <&vcc_ram 2>, <&vcc_ram 3>; + }; + ina226-vcc-pslp { + compatible = "iio-hwmon"; + io-channels = <&vcc_pslp 0>, <&vcc_pslp 1>, <&vcc_pslp 2>, <&vcc_pslp 3>; + }; + ina226-vcc-psfp { + compatible = "iio-hwmon"; + io-channels = <&vcc_psfp 0>, <&vcc_psfp 1>, <&vcc_psfp 2>, <&vcc_psfp 3>; + }; + ina226-vccaux { + compatible = "iio-hwmon"; + io-channels = <&vccaux 0>, <&vccaux 1>, <&vccaux 2>, <&vccaux 3>; + }; + ina226-vccaux-pmc { + compatible = "iio-hwmon"; + io-channels = <&vccaux_pmc 0>, <&vccaux_pmc 1>, <&vccaux_pmc 2>, <&vccaux_pmc 3>; + }; + ina226-vcco-500 { + compatible = "iio-hwmon"; + io-channels = <&vcco_500 0>, <&vcco_500 1>, <&vcco_500 2>, <&vcco_500 3>; + }; + ina226-vcco-501 { + compatible = "iio-hwmon"; + io-channels = <&vcco_501 0>, <&vcco_501 1>, <&vcco_501 2>, <&vcco_501 3>; + }; + ina226-vcco-502 { + compatible = "iio-hwmon"; + io-channels = <&vcco_502 0>, <&vcco_502 1>, <&vcco_502 2>, <&vcco_502 3>; + }; + ina226-vcco-503 { + compatible = "iio-hwmon"; + io-channels = <&vcco_503 0>, <&vcco_503 1>, <&vcco_503 2>, <&vcco_503 3>; + }; + ina226-vcc-1v8 { + compatible = "iio-hwmon"; + io-channels = <&vcc_1v8 0>, <&vcc_1v8 1>, <&vcc_1v8 2>, <&vcc_1v8 3>; + }; + ina226-vcc-3v3 { + compatible = "iio-hwmon"; + io-channels = <&vcc_3v3 0>, <&vcc_3v3 1>, <&vcc_3v3 2>, <&vcc_3v3 3>; + }; + ina226-vcc-1v2-ddr4 { + compatible = "iio-hwmon"; + io-channels = <&vcc_1v2_ddr4 0>, <&vcc_1v2_ddr4 1>, <&vcc_1v2_ddr4 2>, <&vcc_1v2_ddr4 3>; + }; + ina226-vcc-1v1-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v1_lp4 0>, <&vcc1v1_lp4 1>, <&vcc1v1_lp4 2>, <&vcc1v1_lp4 3>; + }; + ina226-vadj-fmc { + compatible = "iio-hwmon"; + io-channels = <&vadj_fmc 0>, <&vadj_fmc 1>, <&vadj_fmc 2>, <&vadj_fmc 3>; + }; + ina226-mgtyavcc { + compatible = "iio-hwmon"; + io-channels = <&mgtyavcc 0>, <&mgtyavcc 1>, <&mgtyavcc 2>, <&mgtyavcc 3>; + }; + ina226-mgtyavtt { + compatible = "iio-hwmon"; + io-channels = <&mgtyavtt 0>, <&mgtyavtt 1>, <&mgtyavtt 2>, <&mgtyavtt 3>; + }; + ina226-mgtyvccaux { + compatible = "iio-hwmon"; + io-channels = <&mgtyvccaux 0>, <&mgtyvccaux 1>, <&mgtyvccaux 2>, <&mgtyvccaux 3>; + }; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&sdhci1 { /* sd1 MIO45-51 cd in place */ + status = "okay"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +/* GEM SGMII */ +&psgtr { + status = "okay"; + /* gem0 */ + clocks = <&si5332_1>; + clock-names = "ref0"; +}; + +&gem0 { + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + is-internal-pcspma; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { /* u131 M88E1512 */ + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "", "", "", "", "", /* 0 - 4 */ + "", "", "DC_SYS_CTRL0", "DC_SYS_CTRL1", "DC_SYS_CTRL2", /* 5 - 9 */ + "DC_SYS_CTRL3", "ZU4_TRIGGER", "SYSCTLR_PB", "", "", /* 10 - 14 */ + "", "", "", "", "", /* 15 - 19 */ + "", "", "", "", "", /* 20 - 24 */ + "", "", "", "", "", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "", "", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD_B", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "", "", "", /* 50 - 54 */ + "", "", "", "", "", /* 55 - 59 */ + "", "", "", "", "", /* 60 - 64 */ + "", "", "", "", "", /* 65 - 69 */ + "", "", "", "", "", /* 70 - 74 */ + "", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "SYSCTLR_VERSAL_MODE0", "SYSCTLR_VERSAL_MODE1", /* 78 - 79 */ + "SYSCTLR_VERSAL_MODE2", "SYSCTLR_VERSAL_MODE3", "SYSCTLR_POR_B_LS", "DC_PRSNT", "", /* 80 - 84 */ + "SYSCTLR_JTAG_S0", "SYSCTLR_JTAG_S1", "SYSCTLR_IIC_MUX0_RESET_B", "SYSCTLR_IIC_MUX1_RESET_B", "", /* 85 - 89 */ + "SYSCTLR_GPIO0", "SYSCTLR_GPIO1", "SYSCTLR_GPIO2", "SYSCTLR_GPIO3", "SYSCTLR_GPIO4", /* 90 - 94 */ + "SYSCTLR_GPIO5", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "PMBUS1_INA226_ALERT", "PMBUS2_INA226_ALERT", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "PMBUS_ALERT", "", "SYSCTLR_ETH_RESET_B", "SYSCTLR_VCC0V85_TG", "MAX6643_OT_B", /* 140 - 144 */ + "MAX6643_FANFINAL_B", "MAX6643_FULLSPD", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "", "", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "MAX6643_FULLSPD", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "FMCP2_FMC_PRSNT_M2C_B", "FMCP1_FMCP_PRSNT_M2C_B", "FMCP2_FMCP_PRSNT_M2C_B", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { /* PMBUS */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* u152 IR35215 0x16/0x46 vcc_soc */ + /* u179 ir38164 0x19/0x49 vcco_500 */ + /* u181 ir38164 0x1a/0x4a vcco_501 */ + /* u183 ir38164 0x1b/0x4b vcco_502 */ + /* u185 ir38164 0x1e/0x4e vadj_fmc */ + /* u187 ir38164 0x1F/0x4f mgtyavcc */ + /* u189 ir38164 0x20/0x50 mgtyavtt */ + /* u194 ir38164 0x13/0x43 vdd1_1v8_lp4 */ + /* u195 ir38164 0x14/0x44 vdd2_1v8_lp4 */ + + irps5401_47: irps5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* pmbus / i2c 0x17 */ + }; + irps5401_4c: irps5401@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* pmbus / i2c 0x1c */ + }; + irps5401_4d: irps5401@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* pmbus / i2c 0x1d */ + }; + }; + i2c@1 { /* PMBUS1_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint"; + reg = <0x40>; + shunt-resistor = <500>; /* R440 */ + /* 0.80V @ 32A 1 of 6 Phases*/ + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-soc"; + reg = <0x41>; + shunt-resistor = <500>; /* R1702 */ + /* 0.80V @ 18A */ + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-pmc"; + reg = <0x42>; + shunt-resistor = <5000>; /* R1214 */ + /* 0.78V @ 500mA */ + }; + vcc_ram: ina226@43 { /* u162 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-ram"; + reg = <0x43>; + shunt-resistor = <5000>; /* r1221 */ + /* 0.78V @ 4A */ + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-pslp"; + reg = <0x44>; + shunt-resistor = <5000>; /* R1216 */ + /* 0.78V @ 1A */ + }; + vcc_psfp: ina226@45 { /* u164 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-psfp"; + reg = <0x45>; + shunt-resistor = <5000>; /* R1219 */ + /* 0.78V @ 2A */ + }; + }; + i2c@2 { /* PCIE_CLK */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* u39 8T49N240 */ + }; + i2c@3 { /* PMBUS2_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccaux"; + reg = <0x40>; + shunt-resistor = <5000>; /* R382 */ + /* 1.5V @ 3A */ + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccaux-pmc"; + reg = <0x41>; + shunt-resistor = <5000>; /* R1246 */ + /* 1.5V @ 500mA */ + }; + vcco_500: ina226@42 { /* u178 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcco-500"; + reg = <0x42>; + shunt-resistor = <2000>; /* R1300 */ + /* 3.3V @ 5A */ + }; + vcco_501: ina226@43 { /* u180 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcco-501"; + reg = <0x43>; + shunt-resistor = <2000>; /* R1313 */ + /* 3.3V @ 5A */ + }; + vcco_502: ina226@44 { /* u182 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcco-502"; + reg = <0x44>; + shunt-resistor = <2000>; /* R1330 */ + /* 3.3V @ 5A */ + }; + vcco_503: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcco-503"; + reg = <0x45>; + shunt-resistor = <5000>; /* R1229 */ + /* 1.8V @ 2A */ + }; + vcc_1v8: ina226@46 { /* u173 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-1v8"; + reg = <0x46>; + shunt-resistor = <5000>; /* R400 */ + /* 1.8V @ 6A */ + }; + vcc_3v3: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-3v3"; + reg = <0x47>; + shunt-resistor = <5000>; /* R1232 */ + /* 3.3V @ 500mA */ + }; + vcc_1v2_ddr4: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-1v2-ddr4"; + reg = <0x48>; + shunt-resistor = <5000>; /* R1275 */ + /* 1.2V @ 4A */ + }; + vcc1v1_lp4: ina226@49 { /* u177 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v1-lp4"; + reg = <0x49>; + shunt-resistor = <5000>; /* R1286 */ + /* 1.1V @ 4A */ + }; + vadj_fmc: ina226@4a { /* u184 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vadj-fmc"; + reg = <0x4a>; + shunt-resistor = <2000>; /* R1350 */ + /* 1.5V @ 10A */ + }; + mgtyavcc: ina226@4b { /* u186 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtyavcc"; + reg = <0x4b>; + shunt-resistor = <2000>; /* R1367 */ + /* 0.88V @ 6A */ + }; + mgtyavtt: ina226@4c { /* u188 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtyavtt"; + reg = <0x4c>; + shunt-resistor = <2000>; /* R1384 */ + /* 1.2V @ 10A */ + }; + mgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtyvccaux"; + reg = <0x4d>; + shunt-resistor = <5000>; /* r1679 */ + /* 1.5V @ 500mA */ + }; + }; + i2c@4 { /* LP_I2C_SM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* FIXME wires ready but chip is missing */ + }; + i2c@5 { /* zSFP_SI570 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + si570_zsfp: clock-generator@5d { /* u192 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_zsfp_clk"; + silabs,skip-recall; + }; + }; + i2c@6 { /* USER_SI570_1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + si570_user1: clock-generator@5f { /* u205 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5f>; + temperature-stability = <50>; + factory-fout = <100000000>; + clock-frequency = <100000000>; + clock-output-names = "si570_user1"; + silabs,skip-recall; + }; + + }; + i2c@7 { /* USER_SI570_2 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* FIXME wires ready but chip is missing */ + }; + }; +}; + +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + i2c-mux-idle-disconnect; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + dc_i2c: i2c@0 { /* DC_I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* 0x5c too */ + }; + si570_ref_clk: clock-generator@5d { /* u32 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "ref_clk"; + silabs,skip-recall; + }; + /* and connector J212D */ + eeprom_ebm: eeprom@52 { /* x-ebm module */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x52>; + }; + }; + fmc1: i2c@1 { /* FMCP1_IIC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME connection to Samtec J51C */ + /* expected eeprom 0x50 FMC cards */ + eeprom_fmc1: eeprom@50 { + compatible = "st,24c128", "atmel,24c128"; + reg = <0x50>; + }; + }; + fmc2: i2c@2 { /* FMCP2_IIC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* FIXME connection to Samtec J53C */ + /* expected eeprom 0x50 FMC cards */ + eeprom_fmc2: eeprom@50 { + compatible = "st,24c128", "atmel,24c128"; + reg = <0x50>; + }; + }; + i2c@3 { /* DDR4_DIMM1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_ddr_dimm1: clock-generator@60 { /* u2 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "si570_ddrdimm1_clk"; + silabs,skip-recall; + }; + }; + i2c@4 { /* LPDDR4_SI570_CLK2 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + si570_lpddr4clk2: clock-generator@60 { /* u3 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "si570_lpddr4_clk2"; + silabs,skip-recall; + }; + }; + i2c@5 { /* LPDDR4_SI570_CLK1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + si570_lpddr4clk1: clock-generator@60 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "si570_lpddr4_clk1"; + silabs,skip-recall; + }; + }; + i2c@6 { /* HSDP_SI570 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + si570_hsdp: clock-generator@5d { /* u5 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_hsdp_clk"; + silabs,skip-recall; + }; + }; + i2c@7 { /* 8A34001 - U219B and J310 connector */ + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; + i2c-mux@75 { /* u214 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + i2c@0 { /* SFP0_IIC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* SFP0 */ + }; + i2c@1 { /* SFP1_IIC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* SFP1 */ + }; + i2c@2 { /* QSFP1_I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* QSFP1 */ + }; + /* 3 - 7 unused */ + }; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-e-a2197-00-revB.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-e-a2197-00-revB.dts @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevB System Controller + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include "zynqmp-e-a2197-00-revA.dts" + +/ { + model = "Versal System Controller on a2197 Eval board RevB"; /* VCK190/VMK180 */ + compatible = "xlnx,zynqmp-e-a2197-00-revB", "xlnx,zynqmp-a2197-revB", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + /delete-node/ ina226-vcco-500; + /delete-node/ ina226-vcco-501; + /delete-node/ ina226-vcco-502; +}; + +&i2c0 { + i2c-mux@74 { /* u33 */ + i2c@2 { /* PCIE_CLK */ + /delete-node/ clock-generator@6c; + }; + i2c@3 { /* PMBUS2_INA226 */ + /delete-node/ ina226@42; + /delete-node/ ina226@43; + /delete-node/ ina226@44; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-g-a2197-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-g-a2197-00-revA.dts @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller on MGT + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include + +/ { + model = "Versal System Controller on a2197 MGT Char board RevA"; + compatible = "xlnx,zynqmp-g-a2197-00-revA", "xlnx,zynqmp-a2197-revA", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + mmc0 = &sdhci0; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &dcc; + usb0 = &usb0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ina226-u74 { + compatible = "iio-hwmon"; + io-channels = <&u74 0>, <&u74 1>, <&u74 2>, <&u74 3>; + }; + ina226-u75 { + compatible = "iio-hwmon"; + io-channels = <&u75 0>, <&u75 1>, <&u75 2>, <&u75 3>; + }; + ina226-u78 { + compatible = "iio-hwmon"; + io-channels = <&u78 0>, <&u78 1>, <&u78 2>, <&u78 3>; + }; + ina226-u79 { + compatible = "iio-hwmon"; + io-channels = <&u79 0>, <&u79 1>, <&u79 2>, <&u79 3>; + }; + ina226-u82 { + compatible = "iio-hwmon"; + io-channels = <&u82 0>, <&u82 1>, <&u82 2>, <&u82 3>; + }; + ina226-u84 { + compatible = "iio-hwmon"; + io-channels = <&u84 0>, <&u84 1>, <&u84 2>, <&u84 3>; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&gem0 { /* eth MDIO 76/77 */ + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + is-internal-pcspma; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { /* marwell m88e1512 */ + reg = <0>; + reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>; +/* xlnx,phy-type = ; */ + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "", "", "", "", "", /* 0 - 4 */ + "", "", "", "", "", /* 5 - 9 */ + "", "", "", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "", "", "", "", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "", "", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "", "", "ETH_RESET_B", "", "", /* 40 - 44 */ + "", "", "", "", "", /* 45 - 49 */ + "", "", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "", /* 60 - 64 */ + "", "", "", "", "", /* 65 - 69 */ + "", "", "", "", "", /* 70 - 74 */ + "", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "SYSCTLR_VERSAL_MODE0", "SYSCTLR_VERSAL_MODE1", /* 78 - 79 */ + "SYSCTLR_VERSAL_MODE2", "SYSCTLR_VERSAL_MODE3", "SYSCTLR_POR_B_LS", "DC_PRSNT", "SYSCTLR_POWER_EN", /* 80 - 84 */ + "SYSCTLR_JTAG_S0", "SYSCTLR_JTAG_S1", "SYSCTLR_IIC_MUX0_RESET_B", "SYSCTLR_IIC_MUX1_RESET_B", "SYSCTLR_LP_I2C_SM_ALERT", /* 85 -89 */ + "SYSCTLR_GPIO0", "SYSCTLR_GPIO1", "SYSCTLR_GPIO2", "SYSCTLR_GPIO3", "SYSCTLR_GPIO4", /* 90 - 94 */ + "SYSCTLR_GPIO5", "VCCO_500_RBIAS", "VCCO_501_RBIAS", "VCCO_502_RBIAS", "VCCO_500_RBIAS_LED", /* 95 - 99 */ + "VCCO_501_RBIAS_LED", "VCCO_502_RBIAS_LED", "SYSCTLR_VCCINT_EN", "SYSCTLR_VCC_IO_SOC_EN", "SYSCTLR_VCC_PMC_EN", /* 100 - 104 */ + "SYSCTLR_VCC_RAM_EN", "SYSCTLR_VCC_PSLP_EN", "SYSCTLR_VCC_PSFP_EN", "SYSCTLR_VCCAUX_EN", "SYSCTLR_VCCAUX_PMC_EN", /* 105 - 109 */ + "SYSCTLR_VCCO_500_EN", "SYSCTLR_VCCO_501_EN", "SYSCTLR_VCCO_502_EN", "SYSCTLR_VCCO_503_EN", "SYSCTLR_VCC1V8_EN", /* 110 - 114 */ + "SYSCTLR_VCC3V3_EN", "SYSCTLR_VCC1V2_DDR4_EN", "SYSCTLR_VCC1V1_LP4_EN", "SYSCTLR_VDD1_1V8_LP4_EN", "SYSCTLR_VADJ_FMC_EN", /* 115 - 119 */ + "SYSCTLR_MGTYAVCC_EN", "SYSCTLR_MGTYAVTT_EN", "SYSCTLR_MGTYVCCAUX_EN", "SYSCTLR_UTIL_1V13_EN", "SYSCTLR_UTIL_1V8_EN", /* 120 - 124 */ + "SYSCTLR_UTIL_2V5_EN", "FMCP1_FMC_PRSNT_M2C_B", "FMCP2_FMC_PRSNT_M2C_B", "FMCP1_FMCP_PRSNT_M2C_B", "FMCP2_FMCP_PRSNT_M2C_B", /* 125 - 129 */ + "PMBUS1_INA226_ALERT", "PMBUS2_INA226_ALERT", "SYSCTLR_USBC_SBU1", "SYSCTLR_USBC_SBU2", "TI_CABLE1", /* 130 - 134 */ + "TI_CABLE2", "SYSCTLR_MIC2005_EN_B", "SYSCTLR_MIC2005_FAULT_B", "SYSCTLR_TUSB320_INT_B", "SYSCTLR_TUSB320_ID", /* 135 - 139 */ + "PMBUS1_ALERT", "PMBUS2_ALERT", "SYSCTLR_ETH_RESET_B", "SYSCTLR_VCC0V85_TG", "MAX6643_OT_B", /* 140 - 144 */ + "MAX6643_FANFINAL_B", "MAX6643_FULLSPD", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + scl-gpios = <&gpio 34 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 35 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + i2c-mux@74 { /* u94 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX0_RESET */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@50 { /* u96 - 24LC32A - 256B */ + compatible = "atmel,24c32"; + reg = <0x50>; + }; + }; + i2c@1 { /* CM_I2C_SCL - Samtec */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + i2c@2 { /* PMBUS - AFX_PMBUS */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + tps544@d { /* u85 */ + compatible = "ti,tps544b25"; + reg = <0xd>; + }; + tps544@10 { /* u73 */ + compatible = "ti,tps544b25"; + reg = <0x10>; + }; + tps544@11 { /* u76 */ + compatible = "ti,tps544b25"; + reg = <0x11>; + }; + tps544@12 { /* u77 */ + compatible = "ti,tps544b25"; + reg = <0x12>; + }; + tps544@13 { /* u80 */ + compatible = "ti,tps544b25"; + reg = <0x13>; + }; + tps544@14 { /* u81 */ + compatible = "ti,tps544b25"; + reg = <0x14>; + }; + tps544@15 { /* u83 */ + compatible = "ti,tps544b25"; + reg = <0x15>; + }; + tps544@16 { /* u63 */ + compatible = "ti,tps544b25"; + reg = <0x16>; + }; + tps544@17 { /* u66 */ + compatible = "ti,tps544b25"; + reg = <0x17>; + }; + tps544@18 { /* u67 */ + compatible = "ti,tps544b25"; + reg = <0x18>; + }; + tps544@19 { /* u69 */ + compatible = "ti,tps544b25"; + reg = <0x19>; + }; + tps544@1d { /* u88 */ + compatible = "ti,tps544b25"; + reg = <0x1d>; + }; + tps544@1e { /* u89 */ + compatible = "ti,tps544b25"; + reg = <0x1e>; + }; + tps544@1f { /* u87 */ + compatible = "ti,tps544b25"; + reg = <0x1f>; + }; + tps544@20 { /* u71 */ + compatible = "ti,tps544b25"; + reg = <0x20>; + }; + u74: ina226@40 { /* u74 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-u74"; + reg = <0x40>; + shunt-resistor = <1000>; + }; + u75: ina226@41 { /* u75 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-u75"; + reg = <0x41>; + shunt-resistor = <1000>; + }; + u78: ina226@42 { /* u78 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-u78"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + u79: ina226@43 { /* u79 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-u79"; + reg = <0x43>; + shunt-resistor = <1000>; + }; + u82: ina226@44 { /* u82 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-u82"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + u84: ina226@45 { /* u84 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-u84"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + tps53681@60 { /* u53 - 0xc0 - FIXME name - don't know what it does - also vcc_io_soc */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + }; + }; + i2c@3 { /* fmc1 via JA2G */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + eeprom_fmc1: eeprom@50 { /* on FMC */ + compatible = "atmel,24c04"; + reg = <0x50>; + }; + }; + i2c@4 { /* fmc2 via JA3G */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + eeprom_fmc2: eeprom@50 { /* on FMC */ + compatible = "atmel,24c04"; + reg = <0x50>; + }; + }; + i2c@5 { /* fmc3 via JA4G */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + eeprom_fmc3: eeprom@50 { /* on FMC */ + compatible = "atmel,24c04"; + reg = <0x50>; + }; + }; + i2c@6 { /* ddr dimm */ + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + /* 7 unused */ + }; +}; + +&usb0 { /* USB0 MIO52-63 */ + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "peripheral"; + maximum-speed = "high-speed"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-m-a2197-01-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-m-a2197-01-revA.dts @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include + +/ { + model = "Versal System Controller on a2197 Memory Char board RevA"; + compatible = "xlnx,zynqmp-m-a2197-01-revA", "xlnx,zynqmp-a2197-revA", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + usb0 = &usb0; + usb1 = &usb1; + spi0 = &qspi; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; /* FIXME don't know how big memory is there */ + }; + + ina226-vcc-aux { + compatible = "iio-hwmon"; + io-channels = <&vcc_aux 0>, <&vcc_aux 1>, <&vcc_aux 2>, <&vcc_aux 3>; + }; + ina226-vcc-ram { + compatible = "iio-hwmon"; + io-channels = <&vcc_ram 0>, <&vcc_ram 1>, <&vcc_ram 2>, <&vcc_ram 3>; + }; + ina226-vcc1v1-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v1_lp4 0>, <&vcc1v1_lp4 1>, <&vcc1v1_lp4 2>, <&vcc1v1_lp4 3>; + }; + ina226-vcc1v2-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2_lp4 0>, <&vcc1v2_lp4 1>, <&vcc1v2_lp4 2>, <&vcc1v2_lp4 3>; + }; + ina226-vdd1-1v8-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vdd1_1v8_lp4 0>, <&vdd1_1v8_lp4 1>, <&vdd1_1v8_lp4 2>, <&vdd1_1v8_lp4 3>; + }; + ina226-vcc0v6-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc0v6_lp4 0>, <&vcc0v6_lp4 1>, <&vcc0v6_lp4 2>, <&vcc0v6_lp4 3>; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ + #address-cells = <1>; + #size-cells = <1>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; /* FIXME tap delay */ +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&uart1 { /* uart1 MIO40-41 */ + status = "okay"; +}; + +&sdhci1 { /* sd1 MIO45-51 cd in place */ + status = "disable"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; /* DTG generates this properly 1512 */ + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; + phy0: ethernet-phy@0 { /* marwell m88e1512 - SGMII */ + reg = <0>; +/* xlnx,phy-type = ; */ + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "SCLK_OUT", "MISO_MO1", "MO2", "MO3", "MOSI_MIO0", /* 0 - 4 */ + "N_SS_OUT", "", "SYS_CTRL0", "SYS_CTRL1", "SYS_CTRL2", /* 5 - 9 */ + "SYS_CTRL3", "SYS_CTRL4", "SYS_CTRL5", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "RXD0_IN", "TXD0_OUT", "TXD1_OUT", "RXD1_IN", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "UART1_TXD_OUT", "UART1_RXD_IN", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD_B", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "USB1_CLK", /* 60 - 64 */ + "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", /* 65 - 69 */ + "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", /* 70 - 74 */ + "USB1_DATA7", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", "", "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + i2c-mux@74 { /* u46 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX0_RESET */ + i2c@0 { /* PMBUS must be enabled via SW21 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + reg_vcc1v2_lp4: tps544@15 { /* u97 */ + compatible = "ti,tps544b25"; + reg = <0x15>; + }; + reg_vcc1v1_lp4: tps544@16 { /* u95 */ + compatible = "ti,tps544b25"; + reg = <0x16>; + }; + reg_vdd1_1v8_lp4: tps544@17 { /* u99 */ + compatible = "ti,tps544b25"; + reg = <0x17>; + }; + /* UTIL_PMBUS connection */ + reg_vcc1v8: tps544@13 { /* u92 */ + compatible = "ti,tps544b25"; + reg = <0x13>; + }; + reg_vcc3v3: tps544@14 { /* u93 */ + compatible = "ti,tps544b25"; + reg = <0x14>; + }; + reg_vcc5v0: tps544@1e { /* u94 */ + compatible = "ti,tps544b25"; + reg = <0x1e>; + }; + }; + i2c@1 { /* PMBUS_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + vcc_aux: ina226@42 { /* u86 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-aux"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc_ram: ina226@43 { /* u81 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-ram"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcc1v1_lp4: ina226@46 { /* u96 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v1-lp4"; + reg = <0x46>; + shunt-resistor = <5000>; + }; + vcc1v2_lp4: ina226@47 { /* u98 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2-lp4"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + vdd1_1v8_lp4: ina226@48 { /* u100 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vdd1-1v8-lp4"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vcc0v6_lp4: ina226@49 { /* u101 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc0v6-lp4"; + reg = <0x49>; + shunt-resistor = <5000>; + }; + }; + i2c@2 { /* PMBUS1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + reg_vccint: tps53681@60 { /* u69 - 0xc0 */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + }; + reg_vcc_pmc: tps544@7 { /* u80 */ + compatible = "ti,tps544b25"; + reg = <0x7>; + }; + reg_vcc_ram: tps544@8 { /* u82 */ + compatible = "ti,tps544b25"; + reg = <0x8>; + }; + reg_vcc_pslp: tps544@9 { /* u83 */ + compatible = "ti,tps544b25"; + reg = <0x9>; + }; + reg_vcc_psfp: tps544@a { /* u84 */ + compatible = "ti,tps544b25"; + reg = <0xa>; + }; + reg_vccaux: tps544@d { /* u85 */ + compatible = "ti,tps544b25"; + reg = <0xd>; + }; + reg_vccaux_pmc: tps544@e { /* u87 */ + compatible = "ti,tps544b25"; + reg = <0xe>; + }; + reg_vcco_500: tps544@f { /* u88 */ + compatible = "ti,tps544b25"; + reg = <0xf>; + }; + reg_vcco_501: tps544@10 { /* u89 */ + compatible = "ti,tps544b25"; + reg = <0x10>; + }; + reg_vcco_502: tps544@11 { /* u90 */ + compatible = "ti,tps544b25"; + reg = <0x11>; + }; + reg_vcco_503: tps544@12 { /* u91 */ + compatible = "ti,tps544b25"; + reg = <0x12>; + }; + }; + i2c@3 { /* MEM PMBUS - FIXME bug in schematics */ + #address-cells = <1>; + #size-cells = <0>; + /* reg = <3>; */ + }; + i2c@4 { /* LP_I2C_SM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* connected to U20G */ + }; + /* 5-7 unused */ + }; +}; + +/* TODO sysctrl via J239 */ +/* TODO samtec J212G/H via J242 */ +/* TODO teensy via U30 PCA9543A bus 1 */ +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + + /* Must be enabled via J242 */ + eeprom_versal: eeprom@51 { /* x-prc-01-revA u116, x-prc-02-revA u12 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + + i2c-mux@74 { /* u47 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX1_RESET */ + dc_i2c: i2c@0 { /* DC_I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u51 - m24128 16kB FIXME addr */ + compatible = "atmel,24c08"; + reg = <0x54>; + }; + si570_ref_clk: clock-generator@5d { /* u26 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; /* FIXME addr */ + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "REF_CLK"; /* FIXME */ + silabs,skip-recall; + }; + /* Connection via Samtec U20D */ + /* Use for storing information about X-PRC card */ + x_prc_eeprom: eeprom@52 { /* x-prc-01-revA u120, x-prc-02-revA u16 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + /* Use for setting up certain features on X-PRC card */ + x_prc_tca9534: gpio@22 { /* x-prc-01-revA u121, x-prc-02-revA u17 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + }; + i2c@2 { /* C0_LP4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_c0_lp4: clock-generator@55 { /* u10 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C0_LP4_SI570_CLK"; + }; + }; + i2c@3 { /* C1_LP4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_c1_lp4: clock-generator@5d { /* u10 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; /* FIXME addr */ + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C1_LP4_SI570_CLK"; + }; + }; + i2c@4 { /* C2_LP4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + si570_c2_lp4: clock-generator@55 { /* u10 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C2_LP4_SI570_CLK"; + }; + }; + i2c@5 { /* C3_LP4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + si570_c3_lp4: clock-generator@55 { /* u15 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C3_LP4_SI570_CLK"; + }; + }; + i2c@6 { /* HSDP_SI570 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + si570_hsdp: clock-generator@5d { /* u19 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; /* FIXME addr */ + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "HSDP_SI570"; + }; + }; + }; +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + /* dr_mode = "peripheral"; */ + maximum-speed = "high-speed"; +}; + +&usb1 { + status = "disabled"; /* not at mem board */ +}; + +&dwc3_1 { + /delete-property/ phy-names ; + /delete-property/ phys ; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk ; + snps,dis_u3_susphy_quirk ; + status = "disabled"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-m-a2197-02-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-m-a2197-02-revA.dts @@ -0,0 +1,494 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include + +/ { + model = "Versal System Controller on a2197 Memory Char board RevA"; + compatible = "xlnx,zynqmp-m-a2197-02-revA", "xlnx,zynqmp-a2197-revA", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + usb0 = &usb0; + usb1 = &usb1; + spi0 = &qspi; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; /* FIXME don't know how big memory is there */ + }; + + ina226-vcc-aux { + compatible = "iio-hwmon"; + io-channels = <&vcc_aux 0>, <&vcc_aux 1>, <&vcc_aux 2>, <&vcc_aux 3>; + }; + ina226-vcc-ram { + compatible = "iio-hwmon"; + io-channels = <&vcc_ram 0>, <&vcc_ram 1>, <&vcc_ram 2>, <&vcc_ram 3>; + }; + ina226-vcc1v1-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v1_lp4 0>, <&vcc1v1_lp4 1>, <&vcc1v1_lp4 2>, <&vcc1v1_lp4 3>; + }; + ina226-vcc1v2-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2_lp4 0>, <&vcc1v2_lp4 1>, <&vcc1v2_lp4 2>, <&vcc1v2_lp4 3>; + }; + ina226-vdd1-1v8-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vdd1_1v8_lp4 0>, <&vdd1_1v8_lp4 1>, <&vdd1_1v8_lp4 2>, <&vdd1_1v8_lp4 3>; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ + #address-cells = <1>; + #size-cells = <1>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; /* FIXME tap delay */ +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&uart1 { /* uart1 MIO40-41 */ + status = "okay"; +}; + +&sdhci1 { /* sd1 MIO45-51 cd in place */ + status = "disable"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; + phy0: ethernet-phy@0 { /* marwell m88e1512 - SGMII */ + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "SCLK_OUT", "MISO_MO1", "MO2", "MO3", "MOSI_MIO0", /* 0 - 4 */ + "N_SS_OUT", "", "SYS_CTRL0", "SYS_CTRL1", "SYS_CTRL2", /* 5 - 9 */ + "SYS_CTRL3", "SYS_CTRL4", "SYS_CTRL5", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "RXD0_IN", "TXD0_OUT", "TXD1_OUT", "RXD1_IN", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "UART1_TXD_OUT", "UART1_RXD_IN", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD_B", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "USB1_CLK", /* 60 - 64 */ + "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", /* 65 - 69 */ + "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", /* 70 - 74 */ + "USB1_DATA7", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", "", "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + i2c-mux@74 { /* u46 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX0_RESET */ + i2c@0 { /* PMBUS must be enabled via SW21 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + reg_vcc1v2_lp4: tps544@15 { /* u97 */ + compatible = "ti,tps544b25"; + reg = <0x15>; + }; + reg_vcc1v1_lp4: tps544@16 { /* u95 */ + compatible = "ti,tps544b25"; + reg = <0x16>; + }; + reg_vdd1_1v8_lp4: tps544@17 { /* u99 */ + compatible = "ti,tps544b25"; + reg = <0x17>; + }; + /* UTIL_PMBUS connection */ + reg_vcc1v8: tps544@13 { /* u92 */ + compatible = "ti,tps544b25"; + reg = <0x13>; + }; + reg_vcc3v3: tps544@14 { /* u93 */ + compatible = "ti,tps544b25"; + reg = <0x14>; + }; + reg_vcc5v0: tps544@1e { /* u94 */ + compatible = "ti,tps544b25"; + reg = <0x1e>; + }; + }; + i2c@1 { /* PMBUS_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + vcc_aux: ina226@42 { /* u86 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-aux"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc_ram: ina226@43 { /* u81 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-ram"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcc1v1_lp4: ina226@46 { /* u96 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v1-lp4"; + reg = <0x46>; + shunt-resistor = <5000>; + }; + vcc1v2_lp4: ina226@47 { /* u98 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2-lp4"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + vdd1_1v8_lp4: ina226@48 { /* u100 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vdd1-1v8-lp4"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + }; + i2c@2 { /* PMBUS1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + reg_vccint: tps53681@60 { /* u69 - 0xc0 */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + }; + reg_vcc_pmc: tps544@7 { /* u80 */ + compatible = "ti,tps544b25"; + reg = <0x7>; + }; + reg_vcc_ram: tps544@8 { /* u82 */ + compatible = "ti,tps544b25"; + reg = <0x8>; + }; + reg_vcc_pslp: tps544@9 { /* u83 */ + compatible = "ti,tps544b25"; + reg = <0x9>; + }; + reg_vcc_psfp: tps544@a { /* u84 */ + compatible = "ti,tps544b25"; + reg = <0xa>; + }; + reg_vccaux: tps544@d { /* u85 */ + compatible = "ti,tps544b25"; + reg = <0xd>; + }; + reg_vccaux_pmc: tps544@e { /* u87 */ + compatible = "ti,tps544b25"; + reg = <0xe>; + }; + reg_vcco_500: tps544@f { /* u88 */ + compatible = "ti,tps544b25"; + reg = <0xf>; + }; + reg_vcco_501: tps544@10 { /* u89 */ + compatible = "ti,tps544b25"; + reg = <0x10>; + }; + reg_vcco_502: tps544@11 { /* u90 */ + compatible = "ti,tps544b25"; + reg = <0x11>; + }; + reg_vcco_503: tps544@12 { /* u91 */ + compatible = "ti,tps544b25"; + reg = <0x12>; + }; + }; + i2c@3 { /* MEM PMBUS - FIXME bug in schematics */ + #address-cells = <1>; + #size-cells = <0>; + /* reg = <3>; */ + }; + i2c@4 { /* LP_I2C_SM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* connected to U20G */ + }; + i2c@5 { /* C0_DDR4_RDIMM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + i2c@6 { /* C2_DDR5_RDIMM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + i2c@7 { /* C3_DDR4_UDIMM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; +}; + +/* TODO sysctrl via J239 */ +/* TODO samtec J212G/H via J242 */ +/* TODO teensy via U30 PCA9543A bus 1 */ +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + + /* Must be enabled via J242 */ + eeprom_versal: eeprom@51 { /* x-prc-01-revA u116, x-prc-02-revA u12 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + + i2c-mux@74 { /* u47 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX1_RESET */ + dc_i2c: i2c@0 { /* DC_I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u51 - m24128 16kB FIXME addr */ + compatible = "atmel,24c08"; + reg = <0x54>; + }; + si570_ref_clk: clock-generator@5d { /* u26 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; /* FIXME addr */ + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "REF_CLK"; /* FIXME */ + silabs,skip-recall; + }; + /* Connection via Samtec U20D */ + /* Use for storing information about X-PRC card */ + x_prc_eeprom: eeprom@52 { /* x-prc-01-revA u120, x-prc-02-revA u16 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + /* Use for setting up certain features on X-PRC card */ + x_prc_tca9534: gpio@22 { /* x-prc-01-revA u121, x-prc-02-revA u17 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + }; + i2c@2 { /* C0_DDR4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_c0_ddr4: clock-generator@55 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C0_DD4_SI570_CLK"; + }; + }; + i2c@3 { /* C1_RLD3 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_c1_lp4: clock-generator@55 { /* u7 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C1_RLD3_SI570_CLK"; + }; + }; + i2c@4 { /* C2_DDR5 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + si570_c2_lp4: clock-generator@55 { /* u10 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C2_DDR5_SI570_CLK"; + }; + }; + i2c@5 { /* C3_DDR4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + si570_c3_lp4: clock-generator@55 { /* u15 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C3_LP4_SI570_CLK"; + }; + }; + i2c@6 { /* HSDP_SI570 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + si570_hsdp: clock-generator@5d { /* u19 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "HSDP_SI570"; + }; + }; + }; +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + /* dr_mode = "peripheral"; */ + maximum-speed = "high-speed"; +}; + +&usb1 { + status = "disabled"; /* not at mem board */ +}; + +&dwc3_1 { + /delete-property/ phy-names ; + /delete-property/ phys ; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk ; + snps,dis_u3_susphy_quirk ; + status = "disabled"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-m-a2197-03-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-m-a2197-03-revA.dts @@ -0,0 +1,488 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include + +/ { + model = "Versal System Controller on a2197 Memory Char board RevA"; + compatible = "xlnx,zynqmp-m-a2197-03-revA", "xlnx,zynqmp-a2197-revA", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + usb0 = &usb0; + usb1 = &usb1; + spi0 = &qspi; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; /* FIXME don't know how big memory is there */ + }; + + ina226-vcc-aux { + compatible = "iio-hwmon"; + io-channels = <&vcc_aux 0>, <&vcc_aux 1>, <&vcc_aux 2>, <&vcc_aux 3>; + }; + ina226-vcc-ram { + compatible = "iio-hwmon"; + io-channels = <&vcc_ram 0>, <&vcc_ram 1>, <&vcc_ram 2>, <&vcc_ram 3>; + }; + ina226-vcc1v1-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v1_lp4 0>, <&vcc1v1_lp4 1>, <&vcc1v1_lp4 2>, <&vcc1v1_lp4 3>; + }; + ina226-vcc1v2-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2_lp4 0>, <&vcc1v2_lp4 1>, <&vcc1v2_lp4 2>, <&vcc1v2_lp4 3>; + }; + ina226-vdd1-1v8-lp4 { + compatible = "iio-hwmon"; + io-channels = <&vdd1_1v8_lp4 0>, <&vdd1_1v8_lp4 1>, <&vdd1_1v8_lp4 2>, <&vdd1_1v8_lp4 3>; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ + #address-cells = <1>; + #size-cells = <1>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; /* FIXME tap delay */ +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&uart1 { /* uart1 MIO40-41 */ + status = "okay"; +}; + +&sdhci1 { /* sd1 MIO45-51 cd in place */ + status = "disable"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; + phy0: ethernet-phy@0 { /* marwell m88e1512 - SGMII */ + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "SCLK_OUT", "MISO_MO1", "MO2", "MO3", "MOSI_MIO0", /* 0 - 4 */ + "N_SS_OUT", "", "SYS_CTRL0", "SYS_CTRL1", "SYS_CTRL2", /* 5 - 9 */ + "SYS_CTRL3", "SYS_CTRL4", "SYS_CTRL5", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "RXD0_IN", "TXD0_OUT", "TXD1_OUT", "RXD1_IN", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "UART1_TXD_OUT", "UART1_RXD_IN", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD_B", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "USB1_CLK", /* 60 - 64 */ + "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", /* 65 - 69 */ + "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", /* 70 - 74 */ + "USB1_DATA7", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", "", "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + i2c-mux@74 { /* u46 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX0_RESET */ + i2c@0 { /* PMBUS must be enabled via SW21 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + reg_vcc1v2_lp4: tps544@15 { /* u97 */ + compatible = "ti,tps544b25"; + reg = <0x15>; + }; + reg_vcc1v1_lp4: tps544@16 { /* u95 */ + compatible = "ti,tps544b25"; + reg = <0x16>; + }; + reg_vdd1_1v8_lp4: tps544@17 { /* u99 */ + compatible = "ti,tps544b25"; + reg = <0x17>; + }; + /* UTIL_PMBUS connection */ + reg_vcc1v8: tps544@13 { /* u92 */ + compatible = "ti,tps544b25"; + reg = <0x13>; + }; + reg_vcc3v3: tps544@14 { /* u93 */ + compatible = "ti,tps544b25"; + reg = <0x14>; + }; + reg_vcc5v0: tps544@1e { /* u94 */ + compatible = "ti,tps544b25"; + reg = <0x1e>; + }; + reg_vcc1v2_ddr4: tps544@18 { /* u3022 */ + compatible = "ti,tps544b25"; + reg = <0x18>; + }; + }; + i2c@1 { /* PMBUS_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + vcc_aux: ina226@42 { /* u86 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-aux"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc_ram: ina226@43 { /* u81 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc-ram"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcc1v1_lp4: ina226@46 { /* u96 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v1-lp4"; + reg = <0x46>; + shunt-resistor = <5000>; + }; + vcc1v2_lp4: ina226@47 { /* u98 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2-lp4"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + vdd1_1v8_lp4: ina226@48 { /* u100 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vdd1-1v8-lp4"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + }; + i2c@2 { /* PMBUS1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + reg_vccint: tps53681@60 { /* u69 - 0xc0 */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + }; + reg_vcc_pmc: tps544@7 { /* u80 */ + compatible = "ti,tps544b25"; + reg = <0x7>; + }; + reg_vcc_ram: tps544@8 { /* u82 */ + compatible = "ti,tps544b25"; + reg = <0x8>; + }; + reg_vcc_pslp: tps544@9 { /* u83 */ + compatible = "ti,tps544b25"; + reg = <0x9>; + }; + reg_vcc_psfp: tps544@a { /* u84 */ + compatible = "ti,tps544b25"; + reg = <0xa>; + }; + reg_vccaux: tps544@d { /* u85 */ + compatible = "ti,tps544b25"; + reg = <0xd>; + }; + reg_vccaux_pmc: tps544@e { /* u87 */ + compatible = "ti,tps544b25"; + reg = <0xe>; + }; + reg_vcco_500: tps544@f { /* u88 */ + compatible = "ti,tps544b25"; + reg = <0xf>; + }; + reg_vcco_501: tps544@10 { /* u89 */ + compatible = "ti,tps544b25"; + reg = <0x10>; + }; + reg_vcco_502: tps544@11 { /* u90 */ + compatible = "ti,tps544b25"; + reg = <0x11>; + }; + reg_vcco_503: tps544@12 { /* u91 */ + compatible = "ti,tps544b25"; + reg = <0x12>; + }; + }; + i2c@3 { /* MEM PMBUS - FIXME bug in schematics */ + #address-cells = <1>; + #size-cells = <0>; + /* reg = <3>; */ + }; + i2c@4 { /* LP_I2C_SM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* connected to U20G */ + }; + i2c@5 { /* DDR4_SODIMM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + }; +}; + +/* TODO sysctrl via J239 */ +/* TODO samtec J212G/H via J242 */ +/* TODO teensy via U30 PCA9543A bus 1 */ +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + + /* Must be enabled via J242 */ + eeprom_versal: eeprom@51 { /* x-prc-01-revA u116, x-prc-02-revA u12 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + + i2c-mux@74 { /* u47 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset connected to SYSCTRL_IIC_MUX1_RESET */ + dc_i2c: i2c@0 { /* DC_I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u51 - m24128 16kB FIXME addr */ + compatible = "atmel,24c08"; + reg = <0x54>; + }; + si570_ref_clk: clock-generator@5d { /* u26 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; /* FIXME addr */ + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "REF_CLK"; /* FIXME */ + silabs,skip-recall; + }; + /* Connection via Samtec U20D */ + /* Use for storing information about X-PRC card */ + x_prc_eeprom: eeprom@52 { /* x-prc-01-revA u120, x-prc-02-revA u16 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + /* Use for setting up certain features on X-PRC card */ + x_prc_tca9534: gpio@22 { /* x-prc-01-revA u121, x-prc-02-revA u17 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + }; + i2c@2 { /* C0_DDR4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_c0_ddr4: clock-generator@55 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C0_DD4_SI570_CLK"; + }; + }; + i2c@3 { /* C1_SODIMM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_c1_lp4: clock-generator@55 { /* u7 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C1_SODIMM_SI570_CLK"; + }; + }; + i2c@4 { /* C2_QDRIV */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + si570_c2_lp4: clock-generator@55 { /* u10 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C2_QDRIV_SI570_CLK"; + }; + }; + i2c@5 { /* C3_DDR4 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + si570_c3_lp4: clock-generator@55 { /* u15 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x55>; + temperature-stability = <50>; + factory-fout = <30000000>; + clock-frequency = <30000000>; + clock-output-names = "C3_LP4_SI570_CLK"; + }; + }; + i2c@6 { /* HSDP_SI570 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + si570_hsdp: clock-generator@5d { /* u19 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "HSDP_SI570"; + }; + }; + }; +}; + +&usb0 { + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + /* dr_mode = "peripheral"; */ + maximum-speed = "high-speed"; +}; + +&usb1 { + status = "disabled"; /* not at mem board */ +}; + +&dwc3_1 { + /delete-property/ phy-names ; + /delete-property/ phys ; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk ; + snps,dis_u3_susphy_quirk ; + status = "disabled"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-01-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-01-revA.dtso @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP System Controller X-PRC-01 revA (SE1) + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,zynqmp-x-prc-01-revA", "xlnx,zynqmp-x-prc-01"; + + fragment@0 { + target = <&dc_i2c>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + x_prc_eeprom: eeprom@52 { /* u120 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + x_prc_tca9534: gpio@22 { /* u121 tca9534 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + }; + }; + + fragment@1 { + target = <&i2c1>; /* Must be enabled via J242 */ + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + eeprom_versal: eeprom@51 { /* u116 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-02-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-02-revA.dtso @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP System Controller X-PRC-02 revA (SE2) + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,zynqmp-x-prc-02-revA", "xlnx,zynqmp-x-prc-02"; + + fragment@0 { + target = <&dc_i2c>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + x_prc_eeprom: eeprom@52 { /* u16 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + x_prc_tca9534: gpio@22 { /* u17 tca9534 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + }; + }; + + fragment@1 { + target = <&i2c1>; /* Must be enabled via J242 */ + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + eeprom_versal: eeprom@51 { /* u12 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-03-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-03-revA.dtso @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP System Controller X-PRC-03 revA (SE3) + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,zynqmp-x-prc-03-revA", "xlnx,zynqmp-x-prc-03"; + + fragment@0 { + target = <&dc_i2c>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + x_prc_eeprom: eeprom@52 { /* u1 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + x_prc_tca9534: gpio@22 { /* u3 tca9534 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + x_prc_si5338: clock-generator@70 { /* U9 */ + compatible = "silabs,si5338"; + reg = <0x70>; /* FIXME */ + }; + }; + }; + + fragment@1 { + target = <&i2c1>; /* Must be enabled via J90/J91 */ + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + eeprom_versal: eeprom@51 { /* u2 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-04-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-04-revA.dtso @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP System Controller X-PRC-04 revA (SE4) + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,zynqmp-x-prc-04-revA", "xlnx,zynqmp-x-prc-04"; + + fragment@0 { + target = <&dc_i2c>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + x_prc_eeprom: eeprom@52 { /* u120 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + x_prc_tca9534: gpio@22 { /* u121 tca9534 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + + si570_gem_tsu: clock-generator@5d { /* u164 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; /* FIXME */ + clock-frequency = <300000000>; + clock-output-names = "si570_gem_tsu_clk"; + }; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + eeprom_versal: eeprom@51 { /* u153 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-05-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA-x-prc-05-revA.dtso @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP System Controller X-PRC-05 revA (SE5) + * + * (C) Copyright 2019 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; +/plugin/; + +/{ + compatible = "xlnx,zynqmp-x-prc-05-revA", "xlnx,zynqmp-x-prc-05"; + + fragment@0 { + target = <&dc_i2c>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + x_prc_eeprom: eeprom@52 { /* u120 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + x_prc_tca9534: gpio@22 { /* u121 tca9534 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + + si570_gem_tsu: clock-generator@5d { /* u164 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; /* FIXME */ + clock-frequency = <300000000>; + clock-output-names = "si570_gem_tsu_clk"; + }; + }; + }; + + fragment@1 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + eeprom_versal: eeprom@51 { /* u153 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-p-a2197-00-revA.dts @@ -0,0 +1,611 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal a2197 RevA System Controller + * + * (C) Copyright 2019, Xilinx, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include + +/ { + model = "Versal System Controller on a2197 Processor Char board RevA"; /* Tenzing */ + compatible = "xlnx,zynqmp-p-a2197-00-revA", "xlnx,zynqmp-a2197-revA", + "xlnx,zynqmp-a2197", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + usb0 = &usb0; + usb1 = &usb1; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ref_clk: ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_ref_clk>; + }; + + ddr4_dimm1_si570: ddr4-dimm1-si570 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_ddr_dimm1>; + }; + + ddr4_dimm2_si570: ddr4-dimm2-si570 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_ddr_dimm2>; + }; + + lpddr4_si570: lpddr4-si570 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_lpddr4>; + }; + + hsdp_si570: hsdp-si570 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&si570_hsdp>; + }; + + si5332_1: si5332-1 { /* clk0_sgmii - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + si5332_2: si5332-2 { /* clk1_usb - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; +}; + +&uart1 { /* uart1 MIO40-41 */ + status = "okay"; +}; + +&sdhci1 { /* sd1 MIO45-51 cd in place */ + status = "okay"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +&psgtr { + status = "okay"; + /* sgmii, usb3 */ + clocks = <&si5332_1>, <&si5332_2>; + clock-names = "ref0", "ref1"; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; /* DTG generates this properly 1512 */ + is-internal-pcspma; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + /* reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; */ + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "", "", "", "", "", /* 0 - 4 */ + "", "", "DC_SYS_CTRL0", "DC_SYS_CTRL1", "DC_SYS_CTRL2", /* 5 - 9 */ + "DC_SYS_CTRL3", "DC_SYS_CTRL4", "DC_SYS_CTRL5", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "", "", "", "", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "UART1_TXD_OUT", "UART1_RXD_IN", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD_B", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "USB1_CLK", /* 60 - 64 */ + "USB1_DIR", "USB1_DATA2", "USB1_NXT", "USB1_DATA0", "USB1_DATA1", /* 65 - 69 */ + "USB1_STP", "USB1_DATA3", "USB1_DATA4", "USB1_DATA5", "USB1_DATA6", /* 70 - 74 */ + "USB1_DATA7", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "SYSCTLR_VERSAL_MODE0", "SYSCTLR_VERSAL_MODE1", /* 78 - 79 */ + "SYSCTLR_VERSAL_MODE2", "SYSCTLR_VERSAL_MODE3", "SYSCTLR_POR_B_LS", "DC_PRSNT", "SYSCTLR_POWER_EN", /* 80 - 84 */ + "SYSCTLR_JTAG_S0", "SYSCTLR_JTAG_S1", "SYSCTLR_IIC_MUX0_RESET_B", "SYSCTLR_IIC_MUX1_RESET_B", "SYSCTLR_LP_I2C_SM_ALERT", /* 85 -89 */ + "SYSCTLR_GPIO0", "SYSCTLR_GPIO1", "SYSCTLR_GPIO2", "SYSCTLR_GPIO3", "SYSCTLR_GPIO4", /* 90 - 94 */ + "SYSCTLR_GPIO5", "VCCO_500_RBIAS", "VCCO_501_RBIAS", "VCCO_502_RBIAS", "VCCO_500_RBIAS_LED", /* 95 - 99 */ + "VCCO_501_RBIAS_LED", "VCCO_502_RBIAS_LED", "SYSCTLR_VCCINT_EN", "SYSCTLR_VCC_IO_SOC_EN", "SYSCTLR_VCC_PMC_EN", /* 100 - 104 */ + "SYSCTLR_VCC_RAM_EN", "SYSCTLR_VCC_PSLP_EN", "SYSCTLR_VCC_PSFP_EN", "SYSCTLR_VCCAUX_EN", "SYSCTLR_VCCAUX_PMC_EN", /* 105 - 109 */ + "SYSCTLR_VCCO_500_EN", "SYSCTLR_VCCO_501_EN", "SYSCTLR_VCCO_502_EN", "SYSCTLR_VCCO_503_EN", "SYSCTLR_VCC1V8_EN", /* 110 - 114 */ + "SYSCTLR_VCC3V3_EN", "SYSCTLR_VCC1V2_DDR4_EN", "SYSCTLR_VCC1V1_LP4_EN", "SYSCTLR_VDD1_1V8_LP4_EN", "SYSCTLR_VADJ_FMC_EN", /* 115 - 119 */ + "SYSCTLR_MGTYAVCC_EN", "SYSCTLR_MGTYAVTT_EN", "SYSCTLR_MGTYVCCAUX_EN", "SYSCTLR_UTIL_1V13_EN", "SYSCTLR_UTIL_1V8_EN", /* 120 - 124 */ + "SYSCTLR_UTIL_2V5_EN", "FMCP1_FMC_PRSNT_M2C_B", "FMCP2_FMC_PRSNT_M2C_B", "FMCP1_FMCP_PRSNT_M2C_B", "FMCP2_FMCP_PRSNT_M2C_B", /* 125 - 129 */ + "PMBUS1_INA226_ALERT", "PMBUS2_INA226_ALERT", "SYSCTLR_USBC_SBU1", "SYSCTLR_USBC_SBU2", "TI_CABLE1", /* 130 - 134 */ + "TI_CABLE2", "SYSCTLR_MIC2005_EN_B", "SYSCTLR_MIC2005_FAULT_B", "SYSCTLR_TUSB320_INT_B", "SYSCTLR_TUSB320_ID", /* 135 - 139 */ + "PMBUS1_ALERT", "PMBUS2_ALERT", "SYSCTLR_ETH_RESET_B", "SYSCTLR_VCC0V85_TG", "MAX6643_OT_B", /* 140 - 144 */ + "MAX6643_FANFINAL_B", "MAX6643_FULLSPD", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { /* PMBUS1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J98 */ + reg_vcc_fmc: tps544@7 { /* u80 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x7>; + regulator-name = "reg_vcc_fmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2600000>; + /* enable-gpio = <&gpio0 23 0x4>; optional */ + }; + reg_vcc_ram: tps544@8 { /* u83 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x8>; + }; + reg_vcc_pslp: tps544@9 { /* u85 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x9>; + }; + reg_vcc_psfp: tps544@a { /* u86 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0xa>; + }; + reg_vccint: tps53681@60 { /* u70 - FIXME name - don't know what it does - also vcc_io_soc */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + /* vccint, vcc_io_soc */ + }; + }; + i2c@1 { /* PMBUS1_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vcc_fmc: ina226@42 { /* u81 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc_ram: ina226@43 { /* u82 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcc_pslp: ina226@44 { /* u84 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; + }; + vcc_psfp: ina226@45 { /* u87 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + }; + i2c@2 { /* PMBUS2 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* On connector J104 */ + reg_vccaus: tps544@d { /* u88 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0xd>; + }; + reg_vccaux_fmc: tps544@e { /* u90 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0xe>; + }; + reg_vcco_500: tps544@f { /* u93 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0xf>; + }; + reg_vcco_501: tps544@10 { /* u95 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x10>; + }; + reg_vcco_502: tps544@11 { /* u97 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x11>; + }; + reg_vcco_503: tps544@12 { /* u99 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x12>; + }; + reg_vcc1v8: tps544@13 { /* u101 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x13>; + }; + reg_vcc3v3: tps544@14 { /* u102 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x14>; + }; + reg_vcc1v2_ddr4: tps544@15 { /* u104 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x15>; + }; + reg_vcc1v1_lp4: tps544@16 { /* u106 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x16>; + }; + reg_vcc1_1V8_lp4: tps544@17 { /* u108 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x17>; + }; + reg_vadj_fmc: tps544@19 { /* u109 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x19>; + }; + reg_mgtyavcc: tps544@1a { /* u111 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x1a>; + }; + reg_mgtyavtt: tps544@1b { /* u114 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x1b>; + }; + reg_mgtyvccaux: tps544@1c { /* u115 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x1c>; + }; + reg_util_1v13: tps544@1d { /* u117 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x1d>; + }; + reg_util_1v8: tps544@1e { /* u118 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x1e>; + }; + reg_util_2v5: tps544@1f { /* u119 - FIXME name - don't know what it does */ + compatible = "ti,tps544b25"; /* Documentation/hwmon/pmbus.rst - wiring is missing */ + reg = <0x1f>; + }; + }; + i2c@3 { /* PMBUS2_INA226 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u89 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccaux_fmc: ina226@41 { /* u91 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcco_500: ina226@42 { /* u92 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcco_501: ina226@43 { /* u94 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcco_502: ina226@44 { /* u96 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; + }; + vcco_503: ina226@45 { /* u98 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + vcc_1v8: ina226@46 { /* u100 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <5000>; + }; + vcc_3v3: ina226@47 { /* u103 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + vcc_1v2_ddr4: ina226@48 { /* u105 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <1000>; + }; + vcc1v1_lp4: ina226@49 { /* u107 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <5000>; + }; + vadj_fmc: ina226@4a { /* u110 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <5000>; + }; + mgtyavcc: ina226@4b { /* u112 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <1000>; + }; + mgtyavtt: ina226@4c { /* u113 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <1000>; + }; + mgtyvccaux: ina226@4d { /* u116 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + vcc_bat: ina226@4e { /* u12 */ + compatible = "ti,ina226"; + reg = <0x4e>; + shunt-resistor = <10000000>; /* 10 ohm */ + }; + }; + i2c@4 { /* LP_I2C_SM */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* connected to J212G */ + /* zynqmp sm alert or samtec J212H */ + }; + /* 5-7 unused */ + }; +}; + +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + + /* Must be enabled via J242 */ + eeprom_versal: eeprom@51 { /* x-prc-01-revA u116, x-prc-02-revA u12 */ + compatible = "atmel,24c02"; + reg = <0x51>; + }; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + dc_i2c: i2c@0 { /* DC_I2C */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; + }; + si570_ref_clk: clock-generator@5d { /* u32 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; /* 570JAC000900DG */ + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "ref_clk"; + silabs,skip-recall; + }; + /* Connection via Samtec J212D */ + /* Use for storing information about X-PRC card */ + x_prc_eeprom: eeprom@52 { /* x-prc-01-revA u120, x-prc-02-revA u16 */ + compatible = "atmel,24c02"; + reg = <0x52>; + }; + + /* Use for setting up certain features on X-PRC card */ + x_prc_tca9534: gpio@22 { /* x-prc-01-revA u121, x-prc-02-revA u17 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "sw4_1", "sw4_2", "sw4_3", "sw4_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "sw4_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "sw4_2"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "sw4_3"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "sw4_4"; + }; + }; + }; + i2c@1 { /* FMCP1_IIC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME connection to Samtec J51C */ + /* expected eeprom 0x50 SE cards */ + }; + i2c@2 { /* FMCP2_IIC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* FIXME connection to Samtec J53C */ + /* expected eeprom 0x50 SE cards */ + }; + i2c@3 { /* DDR4_DIMM1 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_ddr_dimm1: clock-generator@60 { /* u2 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; /* 570BAB000299DG */ + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "si570_ddrdimm1_clk"; + }; + /* 0x50 SPD? */ + }; + i2c@4 { /* DDR4_DIMM2 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + si570_ddr_dimm2: clock-generator@60 { /* u3 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; /* 570BAB000299DG */ + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "si570_ddrdimm2_clk"; + }; + /* 0x50 SPD? */ + }; + i2c@5 { /* LPDDR4_SI570_CLK */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + si570_lpddr4: clock-generator@60 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; /* 570BAB000299DG */ + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "si570_lpddr4_clk"; + }; + }; + i2c@6 { /* HSDP_SI570 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + si570_hsdp: clock-generator@60 { /* u5 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; /* 570JAC000900DG */ + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_hsdp_clk"; + }; + }; + i2c@7 { /* PCIE_CLK */ + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* u36 0xd8 or 0xde - pcie clk buf - 9ZML1241EKILF PCIe GEN 4 CLOCK BUFFER FIXME - no driver */ + /* u37 0xd0 DNP - pcie clocking 1 - 9FGV1006BQ505LTGI - PCIe GEN 4 CLOCK GENERATOR FIXME - no linux driver */ + /* u38 0xca - pcie clocking 2 - 9ZML1241EKILF PCIe GEN 4 CLOCK BUFFER FIXME - no driver */ + /* u39 8T49N240 - pcie clocking 3 */ + }; + }; +}; + +&usb0 { + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 1 PHY_TYPE_USB3 0 1>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "peripheral"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + maximum-speed = "super-speed"; +}; + +&usb1 { + status = "okay"; +}; + +&dwc3_1 { + /delete-property/ phy-names ; + /delete-property/ phys ; + dr_mode = "host"; + maximum-speed = "high-speed"; + snps,dis_u2_susphy_quirk ; + snps,dis_u3_susphy_quirk ; + status = "okay"; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-revB.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-revB.dts @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP Generic System Controller + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2024, Advanced Micro Devices, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include +#include + +/ { + model = "ZynqMP Generic System Controller"; + compatible = "xlnx,zynqmp-sc-revB", "xlnx,zynqmp-sc", "xlnx,zynqmp"; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &dcc; + spi0 = &qspi; + spi1 = &spi0; + spi2 = &spi1; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial1:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + key-fwuen { + label = "sw16"; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + ds40-led { + label = "heartbeat"; + gpios = <&gpio 7 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + ds44-led { + label = "status"; + gpios = <&gpio 8 GPIO_ACTIVE_HIGH>; + }; + }; + + si5332_2: si5332-2 { /* u42 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + pwm-fan { + compatible = "pwm-fan"; + status = "okay"; + pwms = <&ttc0 2 40000 0>; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "QSPI_CLK", "QSPI_DQ1", "QSPI_DQ2", "QSPI_DQ3", "QSPI_DQ0", /* 0 - 4 */ + "QSPI_CS_B", "", "LED1", "LED2", "", /* 5 - 9 */ + "", "ZU4_TRIGGER", "FWUEN", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "I2C1_SCL", /* 20 - 24 */ + "I2C1_SDA", "UART0_RXD", "UART0_TXD", "", "", /* 25 - 29 */ + "", "", "", "", "I2C0_SCL", /* 30 - 34 */ + "I2C0_SDA", "UART1_TXD", "UART1_RXD", "GEM_TX_CLK", "GEM_TX_D0", /* 35 - 39 */ + "GEM_TX_D1", "GEM_TX_D2", "GEM_TX_D3", "GEM_TX_CTL", "GEM_RX_CLK", /* 40 - 44 */ + "GEM_RX_D0", "GEM_RX_D1", "GEM_RX_D2", "GEM_RX_D3", "GEM_RX_CTL", /* 45 - 49 */ + "GEM_MDC", "GEM_MDIO", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "", /* 60 - 64 */ + "", "", "", "", "", /* 65 - 69 */ + "", "", "", "", "", /* 70 - 74 */ + "", "", "ETH_RESET_B", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&gem1 { /* gem1 MIO38-49, MDIO MIO50/51 */ + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <&phy0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@1 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <1>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&gpio 77 GPIO_ACTIVE_LOW>; + reset-assert-us = <100>; + reset-deassert-us = <280>; + }; + }; +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 34 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 35 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +&i2c1 { /* i2c1 MIO 24-25 */ + status = "okay"; + bootph-all; + clock-frequency = <100000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* & 0x5c */ + bootph-all; + }; +}; + +/* USB 3.0 only */ +&psgtr { + status = "okay"; + /* nc, nc, usb3 */ + clocks = <&si5332_2>; + clock-names = "ref2"; +}; + +&qspi { /* MIO 0-5 */ + status = "okay"; + /* QSPI should also have PINCTRL setup */ + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* mt25qu512abb8e12 512Mib */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <40000000>; /* 40MHz */ + partition@0 { + label = "Image Selector"; + reg = <0x0 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@80000 { + label = "Image Selector Golden"; + reg = <0x80000 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@100000 { + label = "Persistent Register"; + reg = <0x100000 0x20000>; /* 128KB */ + }; + partition@120000 { + label = "Persistent Register Backup"; + reg = <0x120000 0x20000>; /* 128KB */ + }; + partition@140000 { + label = "Open_1"; + reg = <0x140000 0xC0000>; /* 768KB */ + }; + partition@200000 { + label = "Image A (FSBL, PMU, ATF, U-Boot)"; + reg = <0x200000 0xD00000>; /* 13MB */ + }; + partition@f00000 { + label = "ImgSel Image A Catch"; + reg = <0xF00000 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@f80000 { + label = "Image B (FSBL, PMU, ATF, U-Boot)"; + reg = <0xF80000 0xD00000>; /* 13MB */ + }; + partition@1c80000 { + label = "ImgSel Image B Catch"; + reg = <0x1C80000 0x80000>; /* 512KB */ + read-only; + lock; + }; + partition@1d00000 { + label = "Open_2"; + reg = <0x1D00000 0x100000>; /* 1MB */ + }; + partition@1e00000 { + label = "Recovery Image"; + reg = <0x1E00000 0x200000>; /* 2MB */ + read-only; + lock; + }; + partition@2000000 { + label = "Recovery Image Backup"; + reg = <0x2000000 0x200000>; /* 2MB */ + read-only; + lock; + }; + partition@2200000 { + label = "U-Boot storage variables"; + reg = <0x2200000 0x20000>; /* 128KB */ + }; + partition@2220000 { + label = "U-Boot storage variables backup"; + reg = <0x2220000 0x20000>; /* 128KB */ + }; + partition@2240000 { + label = "SHA256"; + reg = <0x2240000 0x40000>; /* 256B but 256KB sector */ + read-only; + lock; + }; + partition@2280000 { + label = "Secure OS Storage"; + reg = <0x2280000 0x20000>; /* 128KB */ + }; + partition@22A0000 { + label = "User"; + reg = <0x22A0000 0x1d60000>; /* 29.375 MB */ + }; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings MTFC16GAPALBH 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; +}; + +&ttc0 { + status = "okay"; + #pwm-cells = <3>; +}; + +&uart1 { /* uart0 MIO36-37 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; + +&pinctrl0 { /* required by spec */ + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = ; + power-source = ; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_8_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_8_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_34_grp", "gpio0_35_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_34_grp", "gpio0_35_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = ; + power-source = ; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = ; + power-source = ; + bias-disable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-revC.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-revC.dts @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP Generic System Controller + * + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include "zynqmp-sc-revB.dts" + +/ { + model = "ZynqMP Generic System Controller"; + compatible = "xlnx,zynqmp-sc-revC", "xlnx,zynqmp-sc", "xlnx,zynqmp"; +}; + +&gem1 { /* gem1 MIO38-49, MDIO MIO50/51 */ + /delete-node/ mdio; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@1 { /* ADI1300 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id0283.bc30"; + reg = <1>; + adi,rx-internal-delay-ps = <2400>; + adi,tx-internal-delay-ps = <2400>; + adi,fifo-depth-bits = <8>; + reset-gpios = <&gpio 77 GPIO_ACTIVE_LOW>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vek280-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vek280-revA.dtso @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VEK280 revA + * + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sc-vek280-revA", "xlnx,zynqmp-vek280-revA", + "xlnx,zynqmp-vek280", "xlnx,zynqmp"; + + vc7_xin: vc7-xin { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + gtclk1_1: sys-clk-0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 0>; + }; + + gtclk1_2: sys-clk-1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 1>; + }; + + gtclk1_3: sys-clk-2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 2>; + }; + + gtclk1_6: gtclk1-out6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 3>; + }; + + gtclk1_7: gtclk1-out7 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 4>; + }; + + gtclk1_8: gtclk1-out8 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 5>; + }; + + gtclk1_10: ps-ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 6>; + }; + + gtclk1_11: gtclk1-out11 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7 7>; + }; +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "", "", "SFP_MOD_ABS", "SFP_TX_DISABLE", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "", "FMCP1_FMCP_PRSNT_M2C_B", "", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + ir35215_46: pmic@46 { /* IR35215 - u152 */ + compatible = "infineon,ir35215"; + reg = <0x46>; /* i2c addr - 0x16 */ + }; + irps5401_47: pmic5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* i2c addr 0x17 */ + }; + irps5401_48: pmic@48 { /* IRPS5401 - u279 */ + compatible = "infineon,irps5401"; + reg = <0x48>; /* i2c addr 0x18 */ + }; + ir38064_49: regulator@49 { /* IR38064 - u295 */ + compatible = "infineon,ir38064"; + reg = <0x49>; /* i2c addr 0x19 */ + }; + irps5401_4c: pmic@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* i2c addr 0x1c */ + }; + irps5401_4d: pmic@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* i2c addr 0x1d */ + }; + ir38060_4e: regulator@4e { /* IR38060 - u282 */ + compatible = "infineon,ir38060"; + reg = <0x4e>; /* i2c addr 0x1e */ + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* alerts coming to u233 and SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <500>; /* r440 */ + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <500>; /* r1702 */ + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* r382 */ + }; + vcc_ram: ina226@43 { /* u355 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; /* r2417 */ + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; /* r1830 */ + }; + vcc_psfp: ina226@45 { /* u260 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* r2386 */ + }; + vcco_hdio: ina226@46 { /* u356 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <5000>; /* r2392 */ + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pmbus2_ina226_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* alerts coming to u233 and SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; /* r2384 */ + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; /* r2000 */ + }; + mgtavcc: ina226@42 { /* u265 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* r1829 */ + }; + vcc1v5: ina226@43 { /* u264 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; /* r2397 */ + }; + vcco_mio: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* r2401 */ + }; + mgtavtt: ina226@46 { /* u188 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <500>; /* r1384 */ + }; + vcco_502: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <5000>; /* r1994 */ + }; + mgtvccaux: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <5000>; /* r2384 */ + }; + vcc1v1_lp4: ina226@49 { /* u306 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <500>; /* r2064 */ + }; + vadj_fmc: ina226@4a { /* u281 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <5000>; /* r2031 */ + }; + lpdmgtyavcc: ina226@4b { /* u177 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <5000>; /* r2004 */ + }; + lpdmgtyavtt: ina226@4c { /* u309 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <5000>; /* r1229 */ + }; + lpdmgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <5000>; /* r1679 */ + }; + }; + i2c@4 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + rc21008a_gtclk1: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* connector j374 */ + /* rc21008a at 0x9 u299 */ + vc7: clock-generator@9 { + compatible = "renesas,rc21008a"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + }; + fmcp1_iic: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* to j51c */ + }; + sfp: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* sfp+ connector J376 */ + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vek280-revB.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vek280-revB.dtso @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VEK280 revB + * + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc + * + * Michal Simek + */ + +#include "zynqmp-sc-vek280-revA.dtso" + +&{/} { + compatible = "xlnx,zynqmp-sc-vek280-revB", "xlnx,zynqmp-vek280-revB", + "xlnx,zynqmp-vek280", "xlnx,zynqmp"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vhk158-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vhk158-revA.dtso @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VHK158 revA + * + * (C) Copyright 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sc-vhk158-revA", "xlnx,zynqmp-vhk158-revA", + "xlnx,zynqmp-vhk158", "xlnx,zynqmp"; + + vc7_xin: vc7-xin { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + gtclk1_out1: gtclk1-out1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 0>; + }; + + gtclk1_out2: gtclk1-out2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 1>; + }; + + gtclk1_out3: gtclk1-out3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 2>; + }; + + gtclk1_out6: gtclk1-out6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 3>; + }; + + gtclk1_out7: gtclk1-out7 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 4>; + }; + + gtclk1_out8: gtclk1-out8 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 5>; + }; + + gtclk1_out10: gtclk1-out10 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 6>; + }; + + gtclk2_out1: gtclk2-out1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 0>; + }; + + gtclk2_out2: gtclk2-out2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 1>; + }; + + gtclk2_out3: gtclk2-out3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 2>; + }; + + gtclk2_out6_ddr1: gtclk2-out6-ddr1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 3>; + }; + + gtclk2_out7_ddr2: gtclk2-out7-ddr2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 4>; + }; + + gtclk2_ref_clk: gtclk2-ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 5>; + }; + + gtclk2_out10: gtclk2-out10 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 6>; + }; +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "", "", "QSFPDD1_MODSELL", "QSFPDD2_MODSELL", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "", "FMCP1_FMCP_PRSNT_M2C_B", "", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + ir38064_41: regulator@41 { /* IR38064 - u294 */ + compatible = "infineon,ir38064"; + reg = <0x41>; /* i2c addr 0x11 */ + }; + irps5401_45: pmic5401@45 { /* IRPS5401 - u280 */ + compatible = "infineon,irps5401"; + reg = <0x45>; /* i2c addr 0x15 */ + }; + ir35221_46: pmic@46 { /* IR35221 - u152 */ + compatible = "infineon,ir35221"; + reg = <0x46>; /* i2c addr - 0x16 */ + }; + irps5401_47: pmic5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* i2c addr 0x17 */ + }; + irps5401_48: regulator@48 { /* IRPS5401 - u279 */ + compatible = "infineon,irps5401"; + reg = <0x48>; /* i2c addr 0x18 */ + }; + ir38164_49: regulator@49 { /* IR38164 - u295 */ + compatible = "infineon,ir38164"; + reg = <0x49>; /* i2c addr 0x19 */ + }; + ir38060_4a: regulator@4a { /* IR38060 - u259 */ + compatible = "infineon,ir38164"; + reg = <0x4a>; /* i2c addr 0x1a */ + }; + irps5401_4c: pmic@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* i2c addr 0x1c */ + }; + irps5401_4d: pmic@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* i2c addr 0x1d */ + }; + ir38060_4e: regulator@4e { /* IR38060 - u282 */ + compatible = "infineon,ir38164"; + reg = <0x4e>; /* i2c addr 0x1e */ + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <500>; /* R440 */ + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <500>; /* R1702 */ + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* R382 */ + }; + vcc_ram: ina226@43 { /* u5 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <500>; /* R121 */ + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; /* R1830 */ + }; + vcc_psfp: ina226@45 { /* u260 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* R1834 */ + }; + vcco_hbm: ina226@46 { /* u164 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <500>; /* R2056 */ + }; + vcc_hbm: ina226@47 { /* u307 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <500>; /* R2068 */ + }; + vccaux_hbm: ina226@48 { /* u308 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <5000>; /* R2019 */ + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pmbus2_ina226_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; /* R2060 */ + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <500>; /* R2000 */ + }; + mgtavcc: ina226@42 { /* u265 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <500>; /* R1829 */ + }; + vcc1v5: ina226@43 { /* u264 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <500>; /* R1221 */ + }; + vcco_mio: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <500>; /* R2015 */ + }; + mgtavtt: ina226@46 { /* u188 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <500>; /* R1384 */ + }; + vcco_502: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <500>; /* R1994 */ + }; + mgtvccaux: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <500>; /* R1232 */ + }; + vcc1v2_rdimm: ina226@49 { /* u306 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <500>; /* R2064 */ + }; + vadj_fmc: ina226@4a { /* u281 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <5000>; /* R2031 */ + }; + lpdmgtyavcc: ina226@4b { /* u177 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <500>; /* R2004 */ + }; + lpdmgtyavtt: ina226@4c { /* u309 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <500>; /* R1229 */ + }; + lpdmgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <500>; /* R1679 */ + }; + }; + i2c@4 { /* NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + rc21008a_gtclk1: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + vc7_1: clock-generator@9 { + compatible = "renesas,rc21008a"; + clock-output-names = "rc21008a-0"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + /* i2c@9 - U299 */ + }; + rc21008a_gtclk2: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + vc7_2: clock-generator@9 { + compatible = "renesas,rc21008a"; + clock-output-names = "rc21008a-1"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + /* i2c@9 - U300 */ + }; + sync_8a34001: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* U219 - i2c address UNKNOWN */ + }; + }; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + ddr4_dimm0: i2c@0 { /* wired but NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + fmcp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME connection to Samtec J51C */ + /* expected eeprom 0x50 SE cards */ + }; + qsfp1_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* J350 connector */ + }; + qsfp2_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* J351 connector */ + }; + qsfp3_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* J352 connector */ + }; + qsfp4_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* J353 connector */ + }; + qsfpdd_i2c: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* J1/J2 connectors */ + }; + ddr4_dimm1: i2c@7 { /* wired but NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vm-p-m1369-00-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vm-p-m1369-00-revA.dtso @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VM-P-M1369-00 + * + * Copyright (C) 2024, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sc-vm-p-m1369-revA", + "xlnx,zynqmp-sc-vm-p-m1369", "xlnx,zynqmp"; + + sys_clk_0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&qsfp56g_0_clk 0>; + }; + sys_clk_1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&qsfp56g_1_clk 0>; + }; + sys_clk_2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ch2_lpddr5_refclk 0>; + }; + sys_clk_3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ddr5_dimm1_refclk 0>; + }; + sys_clk_4 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ps_refclk 0>; + }; + + ina226-u19 { + compatible = "iio-hwmon"; + io-channels = <&vcc_soc_ina 0>, <&vcc_soc_ina 1>, <&vcc_soc_ina 2>; + }; + ina226-u287 { + compatible = "iio-hwmon"; + io-channels = <&vcc_ram_ina 0>, <&vcc_ram_ina 1>, <&vcc_ram_ina 2>; + }; + ina226-u288 { + compatible = "iio-hwmon"; + io-channels = <&vcc_pslp_ina 0>, <&vcc_pslp_ina 1>, <&vcc_pslp_ina 2>; + }; + ina226-u289 { + compatible = "iio-hwmon"; + io-channels = <&vccaux_ina 0>, <&vccaux_ina 1>, <&vccaux_ina 2>; + }; + ina226-u290 { + compatible = "iio-hwmon"; + io-channels = <&vccaux_pmc_ina 0>, <&vccaux_pmc_ina 1>, <&vccaux_pmc_ina 2>; + }; + ina226-u291 { + compatible = "iio-hwmon"; + io-channels = <&vcco_500_ina 0>, <&vcco_500_ina 1>, <&vcco_500_ina 2>; + }; + ina226-u292 { + compatible = "iio-hwmon"; + io-channels = <&vcco_501_ina 0>, <&vcco_501_ina 1>, <&vcco_501_ina 2>; + }; + ina226-u293 { + compatible = "iio-hwmon"; + io-channels = <&vcco_502_ina 0>, <&vcco_502_ina 1>, <&vcco_502_ina 2>; + }; + ina226-u294 { + compatible = "iio-hwmon"; + io-channels = <&vcco_503_ina 0>, <&vcco_503_ina 1>, <&vcco_503_ina 2>; + }; + ina226-u295 { + compatible = "iio-hwmon"; + io-channels = <&vcc_ddr5_rdimm_ina 0>, <&vcc_ddr5_rdimm_ina 1>, <&vcc_ddr5_rdimm_ina 2>; + }; + ina226-u298 { + compatible = "iio-hwmon"; + io-channels = <&lp5_1v0_ina 0>, <&lp5_1v0_ina 1>, <&lp5_1v0_ina 2>; + }; + ina226-u296 { + compatible = "iio-hwmon"; + io-channels = <&vcc_fmc_ina 0>, <&vcc_fmc_ina 1>, <&vcc_fmc_ina 2>; + }; + ina226-u299 { + compatible = "iio-hwmon"; + io-channels = <>m_avcc_ina 0>, <>m_avcc_ina 1>, <>m_avcc_ina 2>; + }; + ina226-u300 { + compatible = "iio-hwmon"; + io-channels = <>m_avtt_ina 0>, <>m_avtt_ina 1>, <>m_avtt_ina 2>; + }; + ina226-u301 { + compatible = "iio-hwmon"; + io-channels = <>m_avccaux_ina 0>, <>m_avccaux_ina 1>, <>m_avccaux_ina 2>; + }; + ina226-u297 { + compatible = "iio-hwmon"; + io-channels = <&vcc_mipi_ina 0>, <&vcc_mipi_ina 1>, <&vcc_mipi_ina 2>; + }; +}; + +&i2c1 { /* i2c_main bus */ + #address-cells = <1>; + #size-cells = <0>; + + /* u97 eeprom at 0x54 described in sc-revB - WP protection via BOARD_EEPROM_WP - J1801 */ + + /* i2c_main_1 - u72 - j108 - disable translation, add 8 */ + /* J133 - OE for u91@55 + 8 - 161,132813MHz - QSFP56G_0 */ + qsfp56g_0_clk: clock-controller@5d { + compatible = "renesas,proxo-xp"; + reg = <0x5d>; + #clock-cells = <0>; + clock-output-names = "qsfp56g_0_clk"; + }; + + /* J134 - OE for u92@57 + 8 - 322,265625MHz - QSFP56G_1 */ + qsfp56g_1_clk: clock-controller@5f { + compatible = "renesas,proxo-xp"; + reg = <0x5f>; + #clock-cells = <0>; + clock-output-names = "qsfp56g_1_clk"; + }; + + /* i2c_main_2 - u74 - j110 - disable translation, add 9 */ + /* J210 - OE for u164@50 + 9 - 320MHz - CH2_LP5 */ + ch2_lpddr5_refclk: clock-controller@59 { + compatible = "renesas,proxo-xp"; + reg = <0x59>; + #clock-cells = <0>; + clock-output-names = "ch2_lpddr5_refclk"; + }; + + /* i2c_main_3 - u76 - j112 - disable translation, add 6 */ + /* J231 - OE for u165@50 + 6 - 320MHz - _RDIMM */ + ddr5_dimm1_refclk: clock-controller@56 { + compatible = "renesas,proxo-xp"; + reg = <0x56>; + #clock-cells = <0>; + clock-output-names = "ddr5_udimm_refclk"; + }; + + /* i2c_main_4 - u73 - j109 - disable translation, add 5 */ + /* J117 - OE for u82@50 + 5 - 33,3333MHz - PS_REFCLK */ + ps_refclk: clock-controller@55 { + compatible = "renesas,proxo-xp"; + reg = <0x55>; + #clock-cells = <0>; + clock-output-names = "ps_refclk"; + }; + + /* J71 - selection to LP_I2C_SCL_J or LP_I2C_PMC_SCL_J */ + /* J70 - selection to LP_I2C_SDA_J or LP_I2C_PMC_SDA_J */ + /* this should be SW controlable too */ +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + /* u134 tps544b25 but connected to J178 connector */ + /* u48/IMx3112/0x77 - 1:2 multiplexer - also accessed from Versal NET */ + /* Connection DDR5_UDIMM - SPD can be from 0x50-0x57 */ + /* FIXME gpio should handle SYSCTLR_PMBUS_ALERT and also INA226_PMBUS_ALERT */ + /* Access to i2c_pmc bus via u49 with OE j100 or via SYSCTLR_I2C_PMC_EN */ + + /* ina226_pmbus - J103 - disable INA226_PMBUS */ + vcc_soc_ina: power-monitor@40 { /* u19 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x40>; + shunt-resistor = <1000>; /* R222 */ + }; + + vcc_ram_ina: power-monitor@41 { /* u287 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x41>; + shunt-resistor = <1000>; /* R32981 */ + }; + + vcc_pslp_ina: power-monitor@42 { /* u288 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x42>; + shunt-resistor = <1000>; /* R32984 */ + }; + + vccaux_ina: power-monitor@43 { /* u289 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x43>; + shunt-resistor = <1000>; /* R32987 */ + }; + + vccaux_pmc_ina: power-monitor@44 { /* u290 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x44>; + shunt-resistor = <1000>; /* R32990 */ + }; + + vcco_500_ina: power-monitor@45 { /* u291 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x45>; + shunt-resistor = <1000>; /* R32993 */ + }; + + vcco_501_ina: power-monitor@46 { /* u292 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x46>; + shunt-resistor = <1000>; /* R32996 */ + }; + + vcco_502_ina: power-monitor@47 { /* u293 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x47>; + shunt-resistor = <1000>; /* R32999 */ + }; + + vcco_503_ina: power-monitor@48 { /* u294 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x48>; + shunt-resistor = <1000>; /* R33002 */ + }; + + vcc_ddr5_rdimm_ina: power-monitor@49 { /* u295 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x49>; + shunt-resistor = <1000>; /* R33005 */ + }; + + lp5_1v0_ina: power-monitor@4a { /* u298 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4a>; + shunt-resistor = <1000>; /* R33014 */ + }; + + vcc_fmc_ina: power-monitor@4b { /* u296 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4b>; + shunt-resistor = <1000>; /* R33008 */ + }; + + gtm_avcc_ina: power-monitor@4c { /* u299 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4c>; + shunt-resistor = <1000>; /* R33017 */ + }; + + gtm_avtt_ina: power-monitor@4d { /* u300 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4d>; + shunt-resistor = <1000>; /* R33020 */ + }; + + gtm_avccaux_ina: power-monitor@4e { /* u301 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4e>; + shunt-resistor = <1000>; /* R33023 */ + }; + + vcc_mipi_ina: power-monitor@4f { /* u297 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4f>; + shunt-resistor = <1000>; /* R33011 */ + }; + + /* pmbus - j105 - disable main PMBUS - also going to j102 connector */ + vcc_pslp: regulator@15 { /* u24 */ + compatible = "ti,tps546b24a"; + reg = <0x15>; + }; + + vccaux_pmc: regulator@17 { /* u26 */ + compatible = "ti,tps546b24a"; + reg = <0x17>; + }; + + vcco_500: regulator@18 { /* u27 */ + compatible = "ti,tps546b24a"; + reg = <0x18>; + }; + + vcco_501: regulator@19 { /* u28 */ + compatible = "ti,tps546b24a"; + reg = <0x19>; + }; + + vcco_502: regulator@1a { /* u29 */ + compatible = "ti,tps546b24a"; + reg = <0x1a>; + }; + + vcco_503: regulator@1b { /* u30 */ + compatible = "ti,tps546b24a"; + reg = <0x1b>; + }; + + vcc_ddr5_rdimm: regulator@1c { /* u31 */ + compatible = "ti,tps546b24a"; + reg = <0x1c>; + }; + + gtm_avcc: regulator@22 { /* u37 */ + compatible = "ti,tps546b24a"; + reg = <0x22>; + }; + + gtm_avtt: regulator@20 { /* u38 */ + compatible = "ti,tps546b24a"; + reg = <0x20>; + }; + + gtm_avccaux: regulator@21 { /* u39 */ + compatible = "ti,tps546b24a"; + reg = <0x21>; + }; + + vccint_gt: regulator@2a { /* u44 */ + compatible = "ti,tps546b24a"; + reg = <0x2a>; + }; + + util_1v8: regulator@2b { /* u1839 */ + compatible = "ti,tps546b24a"; + reg = <0x2b>; + }; + + vcc_pmc: regulator@2c { /* u46 */ + compatible = "ti,tps546b24a"; + reg = <0x2c>; + }; + + /* pmbus via U62 as ext_pmbus - disable via j104 */ + vccint: regulator@10 { /* u18 */ + compatible = "ti,tps546b24"; + reg = <0x10>; + }; + + vccsoc: regulator@11 { /* u20 */ + compatible = "ti,tps546b24"; + reg = <0x11>; + }; + + vcc_io: regulator@12 { /* u21 */ + compatible = "ti,tps546b24"; + reg = <0x12>; + }; + + vcc_psfp: regulator@13 { /* u22 */ + compatible = "ti,tps546b24"; + reg = <0x13>; + }; + + vcc_ram: regulator@14 { /* u23 */ + compatible = "ti,tps546b24"; + reg = <0x14>; + }; + + vccaux: regulator@16 { /* u25 */ + compatible = "ti,tps546b24"; + reg = <0x16>; + }; + + lp5_1v0: regulator@1d { /* u32 */ + compatible = "ti,tps546b24"; + reg = <0x1d>; + }; + + vcc_fmc: regulator@1e { /* u33 */ + compatible = "ti,tps546b24"; + reg = <0x1e>; + }; + + lp5_vdd1: regulator@25 { /* u40 */ + compatible = "ti,tps546b24"; + reg = <0x25>; + }; + + lp5_vdd2: regulator@26 { /* u41 */ + compatible = "ti,tps546b24"; + reg = <0x26>; + }; + + lp5_vddq: regulator@27 { /* u42 */ + compatible = "ti,tps546b24"; + reg = <0x27>; + }; + + vcco_hdio: regulator@29 { /* u43 */ + compatible = "ti,tps546b24"; + reg = <0x29>; + }; + + vcc_mipi: regulator@1f { /* u47 */ + compatible = "ti,tps546b24"; + reg = <0x1f>; + }; + + /* connected via J425 connector + ucd90320: power-sequencer@73 { // u16 + compatible = "ti,ucd90320"; + reg = <0x73>; + };*/ +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vn-p-b2197-00-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vn-p-b2197-00-revA.dtso @@ -0,0 +1,496 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VN-P-B2197-00 (Tenzing2) + * + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + #address-cells = <2>; + #size-cells = <2>; + + compatible = "xlnx,zynqmp-sc-vn-p-b2197-revA", + "xlnx,zynqmp-sc-vn-p-b2197", "xlnx,zynqmp"; + + aliases { + nvmem1 = &x_prc_eeprom; + }; + + sys_clk_0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&qsfp56g_0_clk 0>; + }; + sys_clk_1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&qsfp56g_1_clk 0>; + }; + sys_clk_2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr5_c0_clk 0>; + }; + sys_clk_3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr5_c2_clk 0>; + }; + sys_clk_4 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ddr5_udimm_clk 0>; + }; + sys_clk_5 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ps_refclk 0>; + }; + sys_clk_6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ddr4_clk 0>; + }; + + ina226-u1700 { + compatible = "iio-hwmon"; + io-channels = <&vcc_ram_ina 0>, <&vcc_ram_ina 1>, <&vcc_ram_ina 2>; + }; + ina226-u1732 { + compatible = "iio-hwmon"; + io-channels = <&vcc_lpd_ina 0>, <&vcc_lpd_ina 1>, <&vcc_lpd_ina 2>; + }; + ina226-u1733 { + compatible = "iio-hwmon"; + io-channels = <&vccaux_ina 0>, <&vccaux_ina 1>, <&vccaux_ina 2>; + }; + ina226-u1736 { + compatible = "iio-hwmon"; + io-channels = <&vccaux_lpd_ina 0>, <&vccaux_lpd_ina 1>, <&vccaux_lpd_ina 2>; + }; + ina226-u1737 { + compatible = "iio-hwmon"; + io-channels = <&vcco_500_ina 0>, <&vcco_500_ina 1>, <&vcco_500_ina 2>; + }; + ina226-u1739 { + compatible = "iio-hwmon"; + io-channels = <&vcco_501_ina 0>, <&vcco_501_ina 1>, <&vcco_501_ina 2>; + }; + ina226-u1741 { + compatible = "iio-hwmon"; + io-channels = <&vcco_502_ina 0>, <&vcco_502_ina 1>, <&vcco_502_ina 2>; + }; + ina226-u1743 { + compatible = "iio-hwmon"; + io-channels = <&vcco_503_ina 0>, <&vcco_503_ina 1>, <&vcco_503_ina 2>; + }; + ina226-u1745 { + compatible = "iio-hwmon"; + io-channels = <&vcco_700_ina 0>, <&vcco_700_ina 1>, <&vcco_700_ina 2>; + }; + ina226-u1747 { + compatible = "iio-hwmon"; + io-channels = <&vcco_706_ina 0>, <&vcco_706_ina 1>, <&vcco_706_ina 2>; + }; + ina226-u1750 { + compatible = "iio-hwmon"; + io-channels = <>yp_avcc_ina 0>, <>yp_avcc_ina 1>, <>yp_avcc_ina 2>; + }; + ina226-u1752 { + compatible = "iio-hwmon"; + io-channels = <>yp_avtt_ina 0>, <>yp_avtt_ina 1>, <>yp_avtt_ina 2>; + }; + ina226-u1754 { + compatible = "iio-hwmon"; + io-channels = <>yp_avccaux_ina 0>, <>yp_avccaux_ina 1>, <>yp_avccaux_ina 2>; + }; + ina226-u1756 { + compatible = "iio-hwmon"; + io-channels = <>m_avcc_ina 0>, <>m_avcc_ina 1>, <>m_avcc_ina 2>; + }; + ina226-u1758 { + compatible = "iio-hwmon"; + io-channels = <>m_avtt_ina 0>, <>m_avtt_ina 1>, <>m_avtt_ina 2>; + }; + ina226-u1760 { + compatible = "iio-hwmon"; + io-channels = <>m_avccaux_ina 0>, <>m_avccaux_ina 1>, <>m_avccaux_ina 2>; + }; + + /* sc_vpk180_axi_iic_0_0: i2c@80050000 - UNUSED NOW */ /* SI5332 */ + + /* Connect to J212G pin G29/G30 - sysmon connector */ + /* sc_vpk180_axi_iic_1_0: i2c@80060000 */ /* SYSMON */ + + /* FIXME Fan control via u1702 - max6643 and mux via J1703 - not SW controllable - via EMIO */ +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + /* u97 eeprom at 0x54 described in sc-revB - WP protection via BOARD_EEPROM_WP - J1801 */ + /* DC/SE eeprom at 0x52 */ + x_prc_eeprom: eeprom@52 { /* u4 - DC card identification - possible WP */ + compatible = "atmel,24c02"; + reg = <0x52>; + bootph-all; + }; + + x_prc_tca9534: gpio@22 { /* u5 */ + compatible = "nxp,pca9534"; + reg = <0x22>; + gpio-controller; /* IRQ not connected */ + #gpio-cells = <2>; + gpio-line-names = "xprc_sw_1", "xprc_sw_2", "xprc_sw_3", "xprc_sw_4", + "", "", "", ""; + gtr-sel0 { + gpio-hog; + gpios = <0 0>; + input; /* FIXME add meaning */ + line-name = "xprc_sw_1"; + }; + gtr-sel1 { + gpio-hog; + gpios = <1 0>; + input; /* FIXME add meaning */ + line-name = "xprc_sw_1"; + }; + gtr-sel2 { + gpio-hog; + gpios = <2 0>; + input; /* FIXME add meaning */ + line-name = "xprc_sw_1"; + }; + gtr-sel3 { + gpio-hog; + gpios = <3 0>; + input; /* FIXME add meaning */ + line-name = "xprc_sw_1"; + }; + }; + + /* FMC eeproms at 0x50/0x51 */ + /* via j3/j5 to 0x68 to u32/9FGV1006C + + /* i2c_main_1 - u147 - j157 - disable translation, add 8 */ + /* J1 - OE for u43@55 + 8 - 161,132813MHz - QSFP56G_0 */ + qsfp56g_0_clk: clock-controller@5d { + compatible = "renesas,proxo-xp"; + reg = <0x5d>; + #clock-cells = <0>; + clock-output-names = "qsfp56g_0_clk"; + }; + + /* J2 - OE for u41@57 + 8 - 322,265625MHz - QSFP56G_1 */ + qsfp56g_1_clk: clock-controller@5f { + compatible = "renesas,proxo-xp"; + reg = <0x5f>; + #clock-cells = <0>; + clock-output-names = "qsfp56g_1_clk"; + }; + + /* J81 - OE for u115@50 + 8 - 320MHz - LPDDR5_C0 */ + lpddr5_c0_clk: clock-controller@58 { + compatible = "renesas,proxo-xp"; + reg = <0x58>; + #clock-cells = <0>; + clock-output-names = "lpddr5_c0_clk"; + }; + + /* i2c_main_2 - u148 - j122 - disable translation, add 9 */ + /* J112 - OE for u63@50 + 9 - 320MHz - LPDDR5_C2 */ + lpddr5_c2_clk: clock-controller@59 { + compatible = "renesas,proxo-xp"; + reg = <0x59>; + #clock-cells = <0>; + clock-output-names = "lpddr5_c2_clk"; + }; + + /* i2c_main_3 - u149 - j154 - disable translation, add 6 */ + /* J78 - OE for u116@50 + 6 - 320MHz - DDR5_UDIMM */ + ddr5_udimm_clk: clock-controller@56 { + compatible = "renesas,proxo-xp"; + reg = <0x56>; + #clock-cells = <0>; + clock-output-names = "ddr5_udimm_clk"; + }; + + /* i2c_main_4 - u150 - j146 - disable translation, add 5 */ + /* J107 - OE for u39@50 + 5 - 33,3333MHz - PS_REFCLK */ + ps_refclk: clock-controller@55 { + compatible = "renesas,proxo-xp"; + reg = <0x55>; + #clock-cells = <0>; + clock-output-names = "ps_refclk"; + }; + + /* i2c_main_5 - u1782 - j1798 - disable translation, add 7 */ + /* J77 - OE for u1783@50 + 7 - 320MHz - DDR4 */ + ddr4_clk: clock-controller@57 { + compatible = "renesas,proxo-xp"; + reg = <0x57>; + #clock-cells = <0>; + clock-output-names = "ddr4_clk"; + }; + + /* LTC4316 - not wired XORH/XORL - FIXME */ + /* J3 gate - FIXME should be connected for SW handling */ + /* i2c_main_1 bus */ + i2c1_u32: clock-controller@68 { + compatible = "renesas,9fgv1006"; + reg = <0x68>; + }; + + /* J71 - selection to LP_I2C_SCL_J or LP_I2C_PMC_SCL_J */ + /* J70 - selection to LP_I2C_SDA_J or LP_I2C_PMC_SDA_J */ + /* this should be SW controlable too */ +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + /* Via j11/j12 can also go to u17/IML3112 - 1:2 multiplexer - also accessed from Versal NET */ + /* Connection DDR5_UDIMM - SPD can be from 0x50-0x57 */ + /* FIXME gpio should handle SYSCTLR_PMBUS_ALERT and also INA226_PMBUS_ALERT */ + + /* ina226_pmbus - J55 - disable INA226_PMBUS */ + vcc_ram_ina: power-monitor@40 { /* u1700 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x40>; + shunt-resistor = <1000>; /* R1996 */ + }; + + vcc_lpd_ina: power-monitor@41 { /* u1732 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x41>; + shunt-resistor = <1000>; /* R2017 */ + }; + + vccaux_ina: power-monitor@42 { /* u1733 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x42>; + shunt-resistor = <1000>; /* R2037 */ + }; + + vccaux_lpd_ina: power-monitor@43 { /* u1736 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x43>; + shunt-resistor = <1000>; /* R2057 */ + }; + + vcco_500_ina: power-monitor@44 { /* u1737 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x44>; + shunt-resistor = <1000>; /* R2069 */ + }; + + vcco_501_ina: power-monitor@45 { /* u1739 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x45>; + shunt-resistor = <1000>; /* R2089 */ + }; + + vcco_502_ina: power-monitor@46 { /* u1741 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x46>; + shunt-resistor = <1000>; /* R2108 */ + }; + + vcco_503_ina: power-monitor@47 { /* u1743 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x47>; + shunt-resistor = <1000>; /* R2127 */ + }; + + vcco_700_ina: power-monitor@48 { /* u1745 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x48>; + shunt-resistor = <1000>; /* R2154 */ + }; + + vcco_706_ina: power-monitor@49 { /* u1747 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x49>; + shunt-resistor = <1000>; /* R2175 */ + }; + + gtyp_avcc_ina: power-monitor@4a { /* u1750 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4a>; + shunt-resistor = <1000>; /* R2195 */ + }; + + gtyp_avtt_ina: power-monitor@4b { /* u1752 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4b>; + shunt-resistor = <1000>; /* R2215 */ + }; + + gtyp_avccaux_ina: power-monitor@4c { /* u1754 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4c>; + shunt-resistor = <5000>; /* R2235 */ + }; + + gtm_avcc_ina: power-monitor@4d { /* u1756 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4d>; + shunt-resistor = <1000>; /* R2256 */ + }; + + gtm_avtt_ina: power-monitor@4e { /* u1758 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4e>; + shunt-resistor = <1000>; /* R2276 */ + }; + + gtm_avccaux_ina: power-monitor@4f { /* u1760 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + reg = <0x4f>; + shunt-resistor = <5000>; /* R2296 */ + }; + + /* pmbus - J50 - disable main PMBUS - also going to j132 */ + vcc_ram: regulator@a { /* u1730 */ + compatible = "ti,tps544b25"; + reg = <0xa>; + }; + + vcc_lpd: regulator@b { /* u1731 */ + compatible = "ti,tps544b25"; + reg = <0xb>; + }; + + vccaux: regulator@1a { /* u1734 */ + compatible = "ti,tps544b25"; + reg = <0x1a>; + }; + + vcco_503: regulator@12 { /* u1744 */ + compatible = "ti,tps546b24a"; + reg = <0x12>; + }; + + vcco_700: regulator@16 { /* u1746 */ + compatible = "ti,tps544b25"; + reg = <0x16>; + }; + + vcco_706: regulator@17 { /* u1748 */ + compatible = "ti,tps544b25"; + reg = <0x17>; + }; + + gtm_avcc: regulator@23 { /* u1755 */ + compatible = "ti,tps544b25"; + reg = <0x23>; + }; + + gtm_avtt: regulator@24 { /* u1757 */ + compatible = "ti,tps544b25"; + reg = <0x24>; + }; + + gtm_avccaux: regulator@25 { /* u1759 */ + compatible = "ti,tps544b25"; + reg = <0x25>; + }; + + util_1v8: regulator@15 { /* u1765 */ + compatible = "ti,tps544b25"; + reg = <0x15>; + }; + + ucd90320: power-sequencer@73 { /* u1768 */ + compatible = "ti,ucd90320"; + reg = <0x73>; + }; + + /* EXT_PMBUS main - J10 - disable extended PMBUS */ + vccint: tps53681@60 { /* u1712 - J1770 reset jumper */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + /* vccint, vcc_cpm5n */ + }; + + vcc_io_soc: tps53681@61 { /* u1721 - J1772 reset jumper */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x61>; + /* vcc_io_soc, vcc_fpd */ + }; + + vccaux_lpd: regulator@d { /* u1735 */ + compatible = "ti,tps544b25"; + reg = <0xd>; + }; + + vcco_500: regulator@13 { /* u1738 */ + compatible = "ti,tps546b24a"; + reg = <0x13>; + }; + + vcco_501: regulator@10 { /* u1740 */ + compatible = "ti,tps546b24a"; + reg = <0x10>; + }; + + vcco_502: regulator@11 { /* u1742 */ + compatible = "ti,tps546b24a"; + reg = <0x11>; + }; + + gtyp_avcc: regulator@20 { /* u1749 */ + compatible = "ti,tps544b25"; + reg = <0x20>; + }; + + gtyp_avtt: regulator@21 { /* u1751 */ + compatible = "ti,tps544b25"; + reg = <0x21>; + }; + + gtyp_avccaux: regulator@22 { /* u1753 */ + compatible = "ti,tps544b25"; + reg = <0x22>; + }; + + lp5_vdd1_1v8: regulator@e { /* u1761 - FIXME no ina226 */ + compatible = "ti,tps544b25"; + reg = <0xe>; + }; + + lp5_vdd2_1v05: regulator@f { /* u1762 - FIXME no ina226 */ + compatible = "ti,tps544b25"; + reg = <0xf>; + }; + + lp5_vddq_0v5: regulator@14 { /* u1763 - FIXME no ina226 */ + compatible = "ti,tps546b24a"; + reg = <0x14>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vpk120-revB.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vpk120-revB.dtso @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VPK120 revB + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sc-vpk120-revB", "xlnx,zynqmp-vpk120-revB", + "xlnx,zynqmp-vpk120", "xlnx,zynqmp"; + + si570_user1_fmc_clk: si570-user1-fmc-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&user_si570_1>; + }; + + si570_ref_clk: si570-ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ref_clk>; + }; + + si570_lpddr4_clk3: si570-lpddr4-clk3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk3>; + }; + + si570_lpddr4_clk2: si570-lpddr4-clk2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk2>; + }; + + si570_lpddr4_clk1: si570-lpddr4-clk1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk1>; + }; +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "", "", "QSFPDD1_MODSELL", "QSFPDD2_MODSELL", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "", "FMCP1_FMCP_PRSNT_M2C_B", "", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + ir38060_41: regulator@41 { /* IR38060 - u259 */ + compatible = "infineon,ir38060", "infineon,ir38064"; + reg = <0x41>; /* i2c addr 0x11 */ + }; + ir38164_43: regulator@43 { /* IR38164 - u13 */ + compatible = "infineon,ir38164"; + reg = <0x43>; /* i2c addr 0x13 */ + }; + ir35221_46: pmic@46 { /* IR35221 - u152 */ + compatible = "infineon,ir35221"; + reg = <0x46>; /* i2c addr - 0x16 */ + }; + irps5401_47: pmic5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* i2c addr 0x17 */ + }; + ir38164_49: regulator@49 { /* IR38164 - u189 */ + compatible = "infineon,ir38164"; + reg = <0x49>; /* i2c addr 0x19 */ + }; + irps5401_4c: pmic@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* i2c addr 0x1c */ + }; + irps5401_4d: pmic@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* i2c addr 0x1d */ + }; + ir38164_4e: regulator@4e { /* IR38164 - u185 */ + compatible = "infineon,ir38164"; + reg = <0x4e>; /* i2c addr 0x1e */ + }; + ir38164_4f: regulator@4f { /* IR38164 - u187 */ + compatible = "infineon,ir38164"; + reg = <0x4f>; /* i2c addr 0x1f */ + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc_ram: ina226@43 { /* u5 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; + }; + vcc_psfp: ina226@45 { /* u164 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pmbus2_ina226_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + mgtavcc: ina226@42 { /* u265 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc1v5: ina226@43 { /* u264 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcco_mio: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + mgtavtt: ina226@46 { /* u188 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <2000>; + }; + vcco_502: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + mgtvccaux: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vcc1v1_lp4: ina226@49 { /* u186 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <2000>; + }; + vadj_fmc: ina226@4a { /* u184 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <2000>; + }; + lpdmgtyavcc: ina226@4b { /* u177 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <5000>; + }; + lpdmgtyavtt: ina226@4c { /* u260 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <2000>; + }; + lpdmgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + }; + i2c@4 { /* NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + i2c@5 { /* NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + user_si570: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + user_si570_1: clock-generator@5f { /* USER C0 SI570 - u205 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5f>; + temperature-stability = <50>; + factory-fout = <100000000>; + clock-frequency = <100000000>; + clock-output-names = "fmc_si570"; + silabs,skip-recall; + }; + + }; + /* 7 unused */ + }; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + ref_clk_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + ref_clk: clock-generator@5d { /* u32 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "ref_clk"; + silabs,skip-recall; + }; + }; + fmcp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME connection to Samtec J51C */ + /* expected eeprom 0x50 SE cards */ + }; + i2c@2 { /* NC - FIXME */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + lpddr4_si570_clk3_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + lpddr4_clk3: clock-generator@60 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk3"; + silabs,skip-recall; + }; + }; + lpddr4_si570_clk2_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + lpddr4_clk2: clock-generator@60 { /* u3 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk2"; + silabs,skip-recall; + }; + }; + lpddr4_si570_clk1_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + lpddr4_clk1: clock-generator@60 { /* u248 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk1"; + silabs,skip-recall; + }; + }; + qsfpdd_i2c: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* J1/J2 connectors */ + }; + idt8a34001_i2c: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* Via J310 connector */ + idt_8a34001: phc@5b { + compatible = "idt,8a34001"; /* u219B */ + reg = <0x5b>; /* FIXME not in schematics */ + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vpk180-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vpk180-revA.dtso @@ -0,0 +1,496 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VPK180 revA + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sc-vpk180-revA", "xlnx,zynqmp-vpk180-revA", + "xlnx,zynqmp-vpk180", "xlnx,zynqmp"; + + si570_ref_clk: si570-ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ref_clk>; + }; + + si570_lpddr4_clk3: si570-lpddr4-clk3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk3>; + }; + + si570_lpddr4_clk2: si570-lpddr4-clk2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk2>; + }; + + si570_lpddr4_clk1: si570-lpddr4-clk1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk1>; + }; + + vc7_xin: vc7-xin { + compatible = "fixed-clock"; + #clock-cells = <0x0>; + clock-frequency = <50000000>; + }; + + gtclk1_out0: gtclk1-out0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 0>; + }; + + gtclk1_out1: gtclk1-out1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 1>; + }; + + gtclk1_out2: gtclk1-out2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 2>; + }; + + gtclk1_out3: gtclk1-out3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 3>; + }; + + gtclk1_out4: gtclk1-out4 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 4>; + }; + + gtclk1_out5: gtclk1-out5 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 5>; + }; + + gtclk1_out6: gtclk1-out6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 6>; + }; + + gtclk1_out7: gtclk1-out7 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 7>; + }; + + gtclk2_out0: gtclk2-out0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 0>; + }; + + gtclk2_out1: gtclk2-out1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 1>; + }; + + gtclk2_out2: gtclk2-out2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 2>; + }; + + gtclk2_out3: gtclk2-out3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 3>; + }; + + gtclk2_out4: gtclk2-out4 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 4>; + }; + + gtclk2_out5: gtclk2-out5 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 5>; + }; + + gtclk2_out6: gtclk2-out6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 6>; + }; + + gtclk2_out7: gtclk2-out7 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 7>; + }; +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "QSFPDD1_MODSELL", "QSFPDD2_MODSELL", "QSFPDD3_MODSELL", "QSFPDD4_MODSELL", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "QSFPDD5_MODSELL", "QSFPDD6_MODSELL", "", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "", "FMCP1_FMCP_PRSNT_M2C_B", "UTIL_3V3_VRHOT_B", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + ir38060_41: regulator@41 { /* IR38060 - u259 */ + compatible = "infineon,ir38060", "infineon,ir38064"; + reg = <0x41>; /* i2c addr 0x11 */ + }; + ir35221_45: pmic@45 { /* IR35221 - u291 */ + compatible = "infineon,ir35221"; + reg = <0x45>; /* i2c addr - 0x15 */ + }; + ir35221_46: pmic@46 { /* IR35221 - u152 */ + compatible = "infineon,ir35221"; + reg = <0x46>; /* i2c addr - 0x16 */ + }; + irps5401_47: pmic5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* i2c addr 0x17 */ + }; + irps5401_48: pmic@48 { /* IRPS5401 - u295 */ + compatible = "infineon,irps5401"; + reg = <0x48>; /* i2c addr 0x18 */ + }; + ir38164_49: regulator@49 { /* IR38164 - u189 */ + compatible = "infineon,ir38164"; + reg = <0x49>; /* i2c addr 0x19 */ + }; + irps5401_4c: pmic@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* i2c addr 0x1c */ + }; + irps5401_4d: pmic@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* i2c addr 0x1d */ + }; + ir38164_4e: regulator@4e { /* IR38164 - u185 */ + compatible = "infineon,ir38164"; + reg = <0x4e>; /* i2c addr 0x1e */ + }; + ir38164_4f: regulator@4f { /* IR38164 - u187 */ + compatible = "infineon,ir38164"; + reg = <0x4f>; /* i2c addr 0x1f */ + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; /* r440 */ + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; /* r2174 */ + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* r1214 */ + }; + vcc_ram: ina226@43 { /* u5 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; /* r2108 */ + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; /* r1830 */ + }; + vcc_psfp: ina226@45 { /* u164 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* r2086 */ + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pmbus2_ina226_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <2000>; /* r2109 */ + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; /* r1246 */ + }; + mgtavcc: ina226@42 { /* u265 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* r1829 */ + }; + vcc1v5: ina226@43 { /* u264 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; /* r1221 */ + }; + vcco_mio: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* r1219 */ + }; + mgtavtt: ina226@46 { /* u188 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <2000>; /* r1384 */ + }; + vcco_502: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <5000>; /* r1825 */ + }; + mgtvccaux: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <5000>; /* r1232 */ + }; + vcc1v1_lp4: ina226@49 { /* u186 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <2000>; /* r1367 */ + }; + vadj_fmc: ina226@4a { /* u184 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <2000>; /* r1350 */ + }; + lpdmgtyavcc: ina226@4b { /* u177 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <5000>; /* r2097 */ + }; + lpdmgtyavtt: ina226@4c { /* u260 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <2000>; /* r1834 */ + }; + lpdmgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <5000>; /* r1679 */ + }; + }; + /* 4 - 7 unused */ + }; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + i2c-mux-idle-disconnect; + /* reset-gpios = <&PL_GPIO SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + ref_clk_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + ref_clk: clock-generator@5d { /* u32 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "ref_clk"; + silabs,skip-recall; + }; + }; + fmcp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* connection to Samtec J51C */ + /* expected eeprom 0x50 SE cards */ + }; + osfp_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* J362 connector */ + }; + lpddr4_si570_clk3_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + lpddr4_clk3: clock-generator@60 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk3"; + silabs,skip-recall; + }; + /* alternative option DNP - u305 at 0x50 */ + }; + lpddr4_si570_clk2_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + lpddr4_clk2: clock-generator@60 { /* u3 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk2"; + silabs,skip-recall; + }; + /* alternative option DNP - u303 at 0x50 */ + }; + lpddr4_si570_clk1_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + lpddr4_clk1: clock-generator@60 { /* u248 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk1"; + silabs,skip-recall; + }; + /* alternative option DNP - u301 at 0x50 */ + }; + qsfpdd_i2c: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* J1/J2/J355/J354/J359/J358 connectors */ + }; + idt8a34001_i2c: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* Via J310 connector */ + idt_8a34001: phc@5b { /* u219B */ + compatible = "idt,8a34001"; + reg = <0x5b>; + }; + }; + }; + i2c-mux@75 { /* u322 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + /* reset-gpios = <&PL_GPIO SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + sfpdd1_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* J350 sfp-dd at 0x50 */ + }; + sfpdd2_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* J352 sfp-dd at 0x50 */ + }; + sfpdd3_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* J385 sfp-dd at 0x50 */ + }; + sfpdd4_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* J387 sfp-dd at 0x50 */ + }; + rc21008a_gtclk1_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + vc7_1: clock-generator@9 { + compatible = "renesas,rc21008a"; + clock-output-names = "rc21008a-0"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + /* u298 - rc21008a at 0x9 */ + /* connector J370 */ + }; + rc21008a_gtclk2_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + vc7_2: clock-generator@9 { + compatible = "renesas,rc21008a"; + clock-output-names = "rc21008a-1"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + /* u299 - rc21008a at 0x9 */ + /* connector J371 */ + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sc-vpk180-revB.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sc-vpk180-revB.dtso @@ -0,0 +1,432 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VPK180 revA + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sc-vpk180-revB", "xlnx,zynqmp-vpk180-revB", + "xlnx,zynqmp-vpk180", "xlnx,zynqmp"; + + vc7_xin: vc7-xin { + compatible = "fixed-clock"; + #clock-cells = <0x0>; + clock-frequency = <50000000>; + }; + + gtclk1_out0: gtclk1-out0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 0>; + }; + + gtclk1_out1: gtclk1-out1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 1>; + }; + + gtclk1_out2: gtclk1-out2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 2>; + }; + + gtclk1_out3: gtclk1-out3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 3>; + }; + + gtclk1_out4: gtclk1-out4 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 4>; + }; + + gtclk1_out5: gtclk1-out5 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 5>; + }; + + gtclk1_out6: gtclk1-out6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 6>; + }; + + gtclk1_out7: gtclk1-out7 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_1 7>; + }; + + gtclk2_out0: gtclk2-out0 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 0>; + }; + + gtclk2_out1: gtclk2-out1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 1>; + }; + + gtclk2_out2: gtclk2-out2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 2>; + }; + + gtclk2_out3: gtclk2-out3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 3>; + }; + + gtclk2_out4: gtclk2-out4 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 4>; + }; + + gtclk2_out5: gtclk2-out5 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 5>; + }; + + gtclk2_out6: gtclk2-out6 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 6>; + }; + + gtclk2_out7: gtclk2-out7 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&vc7_2 7>; + }; +}; + +&i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "QSFPDD1_MODSELL", "QSFPDD2_MODSELL", "QSFPDD3_MODSELL", "QSFPDD4_MODSELL", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "QSFPDD5_MODSELL", "QSFPDD6_MODSELL", "", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "", "FMCP1_FMCP_PRSNT_M2C_B", "UTIL_3V3_VRHOT_B", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + ir38060_41: regulator@41 { /* IR38060 - u259 */ + compatible = "infineon,ir38060", "infineon,ir38064"; + reg = <0x41>; /* i2c addr 0x11 */ + }; + ir35221_45: pmic@45 { /* IR35221 - u291 */ + compatible = "infineon,ir35221"; + reg = <0x45>; /* i2c addr - 0x15 */ + }; + ir35221_46: pmic@46 { /* IR35221 - u152 */ + compatible = "infineon,ir35221"; + reg = <0x46>; /* i2c addr - 0x16 */ + }; + irps5401_47: pmic5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* i2c addr 0x17 */ + }; + irps5401_48: pmic@48 { /* IRPS5401 - u295 */ + compatible = "infineon,irps5401"; + reg = <0x48>; /* i2c addr 0x18 */ + }; + ir38164_49: regulator@49 { /* IR38164 - u189 */ + compatible = "infineon,ir38164"; + reg = <0x49>; /* i2c addr 0x19 */ + }; + irps5401_4c: pmic@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* i2c addr 0x1c */ + }; + irps5401_4d: pmic@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* i2c addr 0x1d */ + }; + ir38164_4e: regulator@4e { /* IR38164 - u185 */ + compatible = "infineon,ir38164"; + reg = <0x4e>; /* i2c addr 0x1e */ + }; + ir38164_4f: regulator@4f { /* IR38164 - u187 */ + compatible = "infineon,ir38164"; + reg = <0x4f>; /* i2c addr 0x1f */ + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; /* r440 */ + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; /* r2174 */ + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* r1214 */ + }; + vcc_ram: ina226@43 { /* u5 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; /* r2108 */ + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; /* r1830 */ + }; + vcc_psfp: ina226@45 { /* u164 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* r2086 */ + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pmbus2_ina226_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <2000>; /* r2109 */ + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; /* r1246 */ + }; + mgtavcc: ina226@42 { /* u265 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; /* r1829 */ + }; + vcc1v5: ina226@43 { /* u264 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; /* r1221 */ + }; + vcco_mio: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; /* r1219 */ + }; + mgtavtt: ina226@46 { /* u188 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <2000>; /* r1384 */ + }; + vcco_502: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <5000>; /* r1825 */ + }; + mgtvccaux: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <5000>; /* r1232 */ + }; + vcc1v1_lp4: ina226@49 { /* u186 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <2000>; /* r1367 */ + }; + vadj_fmc: ina226@4a { /* u184 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <2000>; /* r1350 */ + }; + lpdmgtyavcc: ina226@4b { /* u177 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <5000>; /* r2097 */ + }; + lpdmgtyavtt: ina226@4c { /* u260 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <2000>; /* r1834 */ + }; + lpdmgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <5000>; /* r1679 */ + }; + }; + /* 4 - 7 unused */ + }; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + i2c-mux-idle-disconnect; + /* reset-gpios = <&PL_GPIO SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + fmcp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* connection to Samtec J51C */ + /* expected eeprom 0x50 SE cards */ + }; + osfp_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* J362 connector */ + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* alternative option DNP - u305 at 0x50 */ + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* alternative option DNP - u303 at 0x50 */ + }; + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* alternative option DNP - u301 at 0x50 */ + }; + qsfpdd_i2c: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* J1/J2/J355/J354/J359/J358 connectors */ + }; + idt8a34001_i2c: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* Via J310 connector */ + idt_8a34001: phc@5b { /* u219B */ + compatible = "idt,8a34001"; + reg = <0x5b>; + }; + }; + }; + i2c-mux@75 { /* u322 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + /* reset-gpios = <&PL_GPIO SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + sfpdd1_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* J350 sfp-dd at 0x50 */ + }; + sfpdd2_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* J352 sfp-dd at 0x50 */ + }; + sfpdd3_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* J385 sfp-dd at 0x50 */ + }; + sfpdd4_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* J387 sfp-dd at 0x50 */ + }; + rc21008a_gtclk1_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + vc7_1: clock-generator@9 { + compatible = "renesas,rc21008a"; + clock-output-names = "rc21008a-0"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + /* u298 - rc21008a at 0x9 */ + /* connector J370 */ + }; + rc21008a_gtclk2_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + vc7_2: clock-generator@9 { + compatible = "renesas,rc21008a"; + clock-output-names = "rc21008a-1"; + reg = <0x9>; + #clock-cells = <1>; + clocks = <&vc7_xin>; + clock-names = "xin"; + }; + /* u299 - rc21008a at 0x9 */ + /* connector J371 */ + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kd-g-revA.dtso @@ -0,0 +1,391 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KD240 revA Carrier Card + * + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kd240-rev1", + "xlnx,zynqmp-sk-kd240-revB", + "xlnx,zynqmp-sk-kd240-revA", + "xlnx,zynqmp-sk-kd240", "xlnx,zynqmp"; + model = "ZynqMP KD240 revA/B/1"; + + ina260-u3 { + compatible = "iio-hwmon"; + io-channels = <&u3 0>, <&u3 1>, <&u3 2>; + }; + + clk_26: clock2 { /* u17 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_25_0: clock4 { /* u92/u91 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: clock5 { /* u92/u91 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&can0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_default>; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + u3: ina260@40 { /* u3 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u13 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "", + "SD_RESET_B", "USB0_HUB_RESET_B", + "", "PS_GEM0_RESET_B", + "", ""; + }; + + hub: usb-hub@2d { /* u36 */ + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; +}; + +/* USB 3.0 */ +&psgtr { + status = "okay"; + /* usb */ + clocks = <&clk_26>; + clock-names = "ref2"; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usb2244: usb-sd { /* u41 */ + compatible = "microchip,usb2244"; + reset-gpios = <&slg7xl45106 2 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; +}; + +&gem1 { /* mdio mio50/51 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + assigned-clock-rates = <250000000>; + + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@8 { /* Adin u31 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id0283.bc30"; + reg = <8>; + adi,rx-internal-delay-ps = <2000>; + adi,tx-internal-delay-ps = <2000>; + adi,fifo-depth-bits = <8>; + reset-assert-us = <10>; + reset-deassert-us = <5000>; + reset-gpios = <&gpio 77 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* 2 more ethernet phys u32@2 and u34@3 */ + +&pinctrl0 { /* required by spec */ + status = "okay"; + + pinctrl_can0_default: can0-default { + mux { + function = "can0"; + groups = "can0_16_grp"; + }; + + conf { + groups = "can0_16_grp"; + slew-rate = ; + power-source = ; + }; + + conf-rx { + pins = "MIO66"; + bias-pull-up; + }; + + conf-tx { + pins = "MIO67"; + bias-pull-up; + drive-strength = <4>; + }; + }; + + pinctrl_uart0_default: uart0-default { + conf { + groups = "uart0_17_grp"; + slew-rate = ; + power-source = ; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO70"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO71"; + bias-disable; + }; + + mux { + groups = "uart0_17_grp"; + function = "uart0"; + }; + }; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = ; + power-source = ; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + output-enable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = ; + power-source = ; + }; + + conf-rx { + pins = "MIO45", "MIO46", "MIO47", "MIO48"; + bias-disable; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO44", "MIO49"; + bias-disable; + output-enable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + output-enable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = ; + power-source = ; + bias-disable; + output-enable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = ; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = ; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = ; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = ; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = ; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = ; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart0 { + status = "okay"; + rts-gpios = <&gpio 72 GPIO_ACTIVE_HIGH>; + linux,rs485-enabled-at-boot-time; + rs485-rts-delay = <10 10>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0_default>; + assigned-clock-rates = <100000000>; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; + +&zynqmp_dpsub { + status = "disabled"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revA.dtso @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KR260 revA Carrier Card + * + * (C) Copyright 2021, Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kr260-revA", + "xlnx,zynqmp-sk-kr260", "xlnx,zynqmp"; + model = "ZynqMP KR260 revA"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + + clk_27: clock0 { /* u86 - DP */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_125: si5332-0 { /* u17 - GEM0/1 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clk_74: si5332-5 { /* u17 - SLVC-EC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + clk_26: si5332-2 { /* u17 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_156: si5332-3 { /* u17 - SFP+ */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <156250000>; + }; + + clk_25_0: si5332-1 { /* u17 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: si5332-4 { /* u17 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u19 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "USB1_PHY_RESET_B", + "SD_RESET_B", "USB0_HUB_RESET_B", + "USB1_HUB_RESET_B", "PS_GEM0_RESET_B", + "PS_GEM1_RESET_B", ""; + }; + + i2c-mux@74 { /* u18 */ + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + usbhub_i2c0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + hub_1: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + usbhub_i2c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + hub_2: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + /* Bus 2/3 are not connected */ + }; + + /* si5332@6a - u17 - clock-generator */ +}; + +/* GEM SGMII/DP and USB 3.0 */ +&psgtr { + status = "okay"; + /* gem0/1, dp, usb */ + clocks = <&clk_125>, <&clk_27>, <&clk_26>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 1 PHY_TYPE_DP 0 1>; + assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; + +&zynqmp_dpdma { + status = "okay"; + assigned-clock-rates = <600000000>; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usb2244: usb-sd { /* u38 */ + compatible = "microchip,usb2244"; + reset-gpios = <&slg7xl45106 2 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; +}; + +&usb1 { /* mio64 - mio75 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; + reset-gpios = <&slg7xl45106 1 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_1 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub1_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub1_3_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub1_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub1_2_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; +}; + +&gem0 { /* mdio mio50/51 */ + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + is-internal-pcspma; + assigned-clock-rates = <250000000>; +}; + +&gem1 { /* mdio mio50/51, gem mio38 - mio49 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + assigned-clock-rates = <250000000>; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@4 { /* u81 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <4>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <300>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 5 GPIO_ACTIVE_LOW>; + }; + phy1: ethernet-phy@8 { /* u36 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <8>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* gem2/gem3 via PL with phys u79@2 and u80@3 */ + +&pinctrl0 { + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = ; + power-source = ; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + output-enable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = ; + power-source = ; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + output-enable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + output-enable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = ; + power-source = ; + bias-disable; + output-enable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = ; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = ; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = ; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = ; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = ; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = ; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kr-g-revB.dtso @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for KR260 revB Carrier Card (A03 revision) + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include + +/dts-v1/; +/plugin/; + +&{/} { + compatible = "xlnx,zynqmp-sk-kr260-revB", + "xlnx,zynqmp-sk-kr260", "xlnx,zynqmp"; + model = "ZynqMP KR260 revB"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + + clk_125: clock0 { /* u87 - GEM0/1 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + + clk_27: clock1 { /* u86 - DP */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + clk_26: clock2 { /* u89 - USB */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; + + clk_156: clock3 { /* u90 - SFP+ */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <156250000>; + }; + + clk_25_0: clock4 { /* u92/u91 - GEM2 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_25_1: clock5 { /* u92/u91 - GEM3 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + clk_74: clock6 { /* u88 - SLVC-EC */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; +}; + +&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + + slg7xl45106: gpio@11 { /* u19 - reset logic */ + compatible = "dlg,slg7xl45106"; + reg = <0x11>; + label = "resetchip"; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "USB0_PHY_RESET_B", "USB1_PHY_RESET_B", + "SD_RESET_B", "USB0_HUB_RESET_B", + "USB1_HUB_RESET_B", "PS_GEM0_RESET_B", + "PS_GEM1_RESET_B", ""; + }; + + i2c-mux@74 { /* u18 */ + compatible = "nxp,pca9546"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + usbhub_i2c0: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + hub_1: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + usbhub_i2c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + hub_2: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; + }; + /* Bus 2/3 are not connected */ + }; + + /* si5332@6a - u17 - clock-generator */ +}; + +/* GEM SGMII/DP and USB 3.0 */ +&psgtr { + status = "okay"; + /* gem0/1, dp, usb */ + clocks = <&clk_125>, <&clk_27>, <&clk_26>; + clock-names = "ref0", "ref1", "ref2"; +}; + +&zynqmp_dpsub { + status = "okay"; + phy-names = "dp-phy0"; + phys = <&psgtr 1 PHY_TYPE_DP 0 1>; + assigned-clock-rates = <27000000>, <25000000>, <300000000>; +}; + +&zynqmp_dpdma { + status = "okay"; + assigned-clock-rates = <600000000>; +}; + +&usb0 { /* mio52 - mio63 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; + reset-gpios = <&slg7xl45106 0 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; + + usb2244: usb-sd { /* u38 */ + compatible = "microchip,usb2244"; + reset-gpios = <&slg7xl45106 2 GPIO_ACTIVE_LOW>; + }; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub_1>; + reset-gpios = <&slg7xl45106 3 GPIO_ACTIVE_LOW>; + }; +}; + +&usb1 { /* mio64 - mio75 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1_default>; + phy-names = "usb3-phy"; + phys = <&psgtr 3 PHY_TYPE_USB3 1 2>; + reset-gpios = <&slg7xl45106 1 GPIO_ACTIVE_LOW>; + assigned-clock-rates = <250000000>, <20000000>; +}; + +&dwc3_1 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub1_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub1_3_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub1_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub1_2_0>; + i2c-bus = <&hub_2>; + reset-gpios = <&slg7xl45106 4 GPIO_ACTIVE_LOW>; + }; +}; + +&gem0 { /* mdio mio50/51 */ + status = "okay"; + phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; + phy-handle = <&phy0>; + phy-mode = "sgmii"; + is-internal-pcspma; + assigned-clock-rates = <250000000>; +}; + +&gem1 { /* mdio mio50/51, gem mio38 - mio49 */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gem1_default>; + phy-handle = <&phy1>; + phy-mode = "rgmii-id"; + assigned-clock-rates = <250000000>; + + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@4 { /* u81 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <4>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <300>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 5 GPIO_ACTIVE_LOW>; + }; + phy1: ethernet-phy@8 { /* u36 */ + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <8>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,dp83867-rxctrl-strap-quirk; + reset-assert-us = <100>; + reset-deassert-us = <280>; + reset-gpios = <&slg7xl45106 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +/* gem2/gem3 via PL with phys u79@2 and u80@3 */ + +&pinctrl0 { + status = "okay"; + + pinctrl_uart1_default: uart1-default { + conf { + groups = "uart1_9_grp"; + slew-rate = ; + power-source = ; + drive-strength = <12>; + }; + + conf-rx { + pins = "MIO37"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO36"; + bias-disable; + output-enable; + }; + + mux { + groups = "uart1_9_grp"; + function = "uart1"; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + conf { + groups = "i2c1_6_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "i2c1_6_grp"; + function = "i2c1"; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + conf { + groups = "gpio0_24_grp", "gpio0_25_grp"; + slew-rate = ; + power-source = ; + }; + + mux { + groups = "gpio0_24_grp", "gpio0_25_grp"; + function = "gpio0"; + }; + }; + + pinctrl_gem1_default: gem1-default { + conf { + groups = "ethernet1_0_grp"; + slew-rate = ; + power-source = ; + }; + + conf-rx { + pins = "MIO44", "MIO46", "MIO48"; + bias-high-impedance; + low-power-disable; + }; + + conf-bootstrap { + pins = "MIO45", "MIO47", "MIO49"; + bias-disable; + output-enable; + low-power-disable; + }; + + conf-tx { + pins = "MIO38", "MIO39", "MIO40", + "MIO41", "MIO42", "MIO43"; + bias-disable; + output-enable; + low-power-enable; + }; + + conf-mdio { + groups = "mdio1_0_grp"; + slew-rate = ; + power-source = ; + bias-disable; + output-enable; + }; + + mux-mdio { + function = "mdio1"; + groups = "mdio1_0_grp"; + }; + + mux { + function = "ethernet1"; + groups = "ethernet1_0_grp"; + }; + }; + + pinctrl_usb0_default: usb0-default { + conf { + groups = "usb0_0_grp"; + power-source = ; + }; + + conf-rx { + pins = "MIO52", "MIO53", "MIO55"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = ; + }; + + conf-tx { + pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", + "MIO60", "MIO61", "MIO62", "MIO63"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = ; + }; + + mux { + groups = "usb0_0_grp"; + function = "usb0"; + }; + }; + + pinctrl_usb1_default: usb1-default { + conf { + groups = "usb1_0_grp"; + power-source = ; + }; + + conf-rx { + pins = "MIO64", "MIO65", "MIO67"; + bias-high-impedance; + drive-strength = <12>; + slew-rate = ; + }; + + conf-tx { + pins = "MIO66", "MIO68", "MIO69", "MIO70", "MIO71", + "MIO72", "MIO73", "MIO74", "MIO75"; + bias-disable; + output-enable; + drive-strength = <4>; + slew-rate = ; + }; + + mux { + groups = "usb1_0_grp"; + function = "usb1"; + }; + }; +}; + +&uart1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso @@ -22,6 +22,17 @@ /plugin/; &{/} { + compatible = "xlnx,zynqmp-sk-kv260-revA", + "xlnx,zynqmp-sk-kv260-revY", + "xlnx,zynqmp-sk-kv260-revZ", + "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp"; + model = "ZynqMP KV260 revA"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + si5332_0: si5332-0 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; @@ -68,7 +79,12 @@ scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - /* u14 - 0x40 - ina260 */ + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ }; @@ -113,7 +129,6 @@ pinctrl-0 = <&pinctrl_usb0_default>; phy-names = "usb3-phy"; phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; - /* missing usb5744 - u43 */ }; &dwc3_0 { @@ -121,6 +136,24 @@ dr_mode = "host"; snps,usb3_lpm_capable; maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; }; &sdhci1 { /* on CC with tuned parameters */ @@ -139,7 +172,7 @@ bus-width = <4>; }; -&gem3 { /* required by spec */ +&gem3 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; @@ -166,9 +199,28 @@ }; }; -&pinctrl0 { /* required by spec */ +&pinctrl0 { status = "okay"; + pinctrl_gpio0_default: gpio0-default { + conf { + groups = "gpio0_38_grp"; + bias-pull-up; + power-source = ; + }; + + mux { + groups = "gpio0_38_grp"; + function = "gpio0"; + }; + + conf-tx { + pins = "MIO38"; + bias-disable; + output-enable; + }; + }; + pinctrl_uart1_default: uart1-default { conf { groups = "uart1_9_grp"; @@ -185,6 +237,7 @@ conf-tx { pins = "MIO36"; bias-disable; + output-enable; }; mux { @@ -207,7 +260,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { conf { groups = "gpio0_24_grp", "gpio0_25_grp"; slew-rate = ; @@ -236,6 +289,7 @@ conf-bootstrap { pins = "MIO71", "MIO73", "MIO75"; bias-disable; + output-enable; low-power-disable; }; @@ -243,6 +297,7 @@ pins = "MIO64", "MIO65", "MIO66", "MIO67", "MIO68", "MIO69"; bias-disable; + output-enable; low-power-enable; }; @@ -251,6 +306,7 @@ slew-rate = ; power-source = ; bias-disable; + output-enable; }; mux-mdio { @@ -281,6 +337,7 @@ pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + output-enable; drive-strength = <4>; slew-rate = ; }; @@ -297,6 +354,7 @@ slew-rate = ; power-source = ; bias-disable; + output-enable; }; conf-cd { @@ -319,6 +377,12 @@ }; }; +&gpio { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio0_default>; +}; + &uart1 { status = "okay"; pinctrl-names = "default"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso @@ -17,6 +17,17 @@ /plugin/; &{/} { + compatible = "xlnx,zynqmp-sk-kv260-rev2", + "xlnx,zynqmp-sk-kv260-rev1", + "xlnx,zynqmp-sk-kv260-revB", + "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp"; + model = "ZynqMP KV260 revB"; + + ina260-u14 { + compatible = "iio-hwmon"; + io-channels = <&u14 0>, <&u14 1>, <&u14 2>; + }; + si5332_0: si5332-0 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; @@ -63,8 +74,16 @@ scl-gpios = <&gpio 24 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; sda-gpios = <&gpio 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - /* u14 - 0x40 - ina260 */ - /* u43 - 0x2d - usb5744 */ + u14: ina260@40 { /* u14 */ + compatible = "ti,ina260"; + #io-channel-cells = <1>; + label = "ina260-u14"; + reg = <0x40>; + }; + hub: usb-hub@2d { + compatible = "microchip,usb5744"; + reg = <0x2d>; + }; /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ }; @@ -94,6 +113,7 @@ pinctrl-0 = <&pinctrl_usb0_default>; phy-names = "usb3-phy"; phys = <&psgtr 2 PHY_TYPE_USB3 0 1>; + assigned-clock-rates = <250000000>, <20000000>; }; &dwc3_0 { @@ -101,6 +121,26 @@ dr_mode = "host"; snps,usb3_lpm_capable; maximum-speed = "super-speed"; + #address-cells = <1>; + #size-cells = <0>; + + /* 2.0 hub on port 1 */ + hub_2_0: hub@1 { + compatible = "usb424,2744"; + reg = <1>; + peer-hub = <&hub_3_0>; + i2c-bus = <&hub>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; + + /* 3.0 hub on port 2 */ + hub_3_0: hub@2 { + compatible = "usb424,5744"; + reg = <2>; + peer-hub = <&hub_2_0>; + i2c-bus = <&hub>; + reset-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + }; }; &sdhci1 { /* on CC with tuned parameters */ @@ -122,7 +162,7 @@ bus-width = <4>; }; -&gem3 { /* required by spec */ +&gem3 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; @@ -149,9 +189,28 @@ }; }; -&pinctrl0 { /* required by spec */ +&pinctrl0 { status = "okay"; + pinctrl_gpio0_default: gpio0-default { + conf { + groups = "gpio0_38_grp"; + bias-pull-up; + power-source = ; + }; + + mux { + groups = "gpio0_38_grp"; + function = "gpio0"; + }; + + conf-tx { + pins = "MIO38"; + bias-disable; + output-enable; + }; + }; + pinctrl_uart1_default: uart1-default { conf { groups = "uart1_9_grp"; @@ -168,6 +227,7 @@ conf-tx { pins = "MIO36"; bias-disable; + output-enable; }; mux { @@ -190,7 +250,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { conf { groups = "gpio0_24_grp", "gpio0_25_grp"; slew-rate = ; @@ -219,6 +279,7 @@ conf-bootstrap { pins = "MIO71", "MIO73", "MIO75"; bias-disable; + output-enable; low-power-disable; }; @@ -226,6 +287,7 @@ pins = "MIO64", "MIO65", "MIO66", "MIO67", "MIO68", "MIO69"; bias-disable; + output-enable; low-power-enable; }; @@ -234,6 +296,7 @@ slew-rate = ; power-source = ; bias-disable; + output-enable; }; mux-mdio { @@ -264,6 +327,7 @@ pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59", "MIO60", "MIO61", "MIO62", "MIO63"; bias-disable; + output-enable; drive-strength = <4>; slew-rate = ; }; @@ -280,6 +344,7 @@ slew-rate = ; power-source = ; bias-disable; + output-enable; }; conf-cd { @@ -302,6 +367,12 @@ }; }; +&gpio { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio0_default>; +}; + &uart1 { status = "okay"; pinctrl-names = "default"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sm-k24-revA.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP SM-K24 RevA + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include "zynqmp-sm-k26-revA.dts" + +/ { + model = "ZynqMP SM-K24 RevA/B/1"; + compatible = "xlnx,zynqmp-sm-k24-rev1", "xlnx,zynqmp-sm-k24-revB", + "xlnx,zynqmp-sm-k24-revA", "xlnx,zynqmp-sm-k24", + "xlnx,zynqmp"; + + memory@0 { + device_type = "memory"; /* 2GB */ + reg = <0 0 0 0x80000000>; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 /* - * dts file for Xilinx ZynqMP SM-K26 rev1/B/A + * dts file for Xilinx ZynqMP SM-K26 rev2/1/B/A * * (C) Copyright 2020 - 2021, Xilinx, Inc. + * (C) Copyright 2023, Advanced Micro Devices, Inc. * * Michal Simek */ @@ -17,8 +18,9 @@ #include / { - model = "ZynqMP SM-K26 Rev1/B/A"; - compatible = "xlnx,zynqmp-sm-k26-rev1", "xlnx,zynqmp-sm-k26-revB", + model = "ZynqMP SM-K26 Rev2/1/B/A"; + compatible = "xlnx,zynqmp-sm-k26-rev2", + "xlnx,zynqmp-sm-k26-rev1", "xlnx,zynqmp-sm-k26-revB", "xlnx,zynqmp-sm-k26-revA", "xlnx,zynqmp-sm-k26", "xlnx,zynqmp"; @@ -101,12 +103,23 @@ <&xilinx_ams 24>, <&xilinx_ams 25>, <&xilinx_ams 26>, <&xilinx_ams 27>, <&xilinx_ams 28>, <&xilinx_ams 29>; }; + + pwm-fan { + compatible = "pwm-fan"; + status = "okay"; + pwms = <&ttc0 2 40000 1>; + }; }; &modepin_gpio { label = "modepin"; }; +&ttc0 { + status = "okay"; + #pwm-cells = <3>; +}; + &uart1 { /* MIO36/MIO37 */ status = "okay"; }; @@ -234,6 +247,9 @@ pinctrl-0 = <&pinctrl_sdhci0_default>; non-removable; disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; bus-width = <8>; xlnx,mio-bank = <0>; assigned-clock-rates = <187498123>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-smk-k24-revA.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP SMK-K24 RevA + * + * (C) Copyright 2020 - 2021, Xilinx, Inc. + * (C) Copyright 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include "zynqmp-sm-k24-revA.dts" + +/ { + model = "ZynqMP SMK-K24 RevA"; + compatible = "xlnx,zynqmp-smk-k24-revA", "xlnx,zynqmp-smk-k24", + "xlnx,zynqmp"; +}; + +&sdhci0 { + status = "disabled"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 /* - * dts file for Xilinx ZynqMP SMK-K26 rev1/B/A + * dts file for Xilinx ZynqMP SMK-K26 rev2/1/B/A * * (C) Copyright 2020 - 2021, Xilinx, Inc. + * (C) Copyright 2023, Advanced Micro Devices, Inc. * * Michal Simek */ @@ -10,8 +11,9 @@ #include "zynqmp-sm-k26-revA.dts" / { - model = "ZynqMP SMK-K26 Rev1/B/A"; - compatible = "xlnx,zynqmp-smk-k26-rev1", "xlnx,zynqmp-smk-k26-revB", + model = "ZynqMP SMK-K26 Rev2/1/B/A"; + compatible = "xlnx,zynqmp-smk-k26-rev2", + "xlnx,zynqmp-smk-k26-rev1", "xlnx,zynqmp-smk-k26-revB", "xlnx,zynqmp-smk-k26-revA", "xlnx,zynqmp-smk-k26", "xlnx,zynqmp"; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-vp-x-a2785-00-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-vp-x-a2785-00-revA.dts @@ -0,0 +1,442 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP vp-x-a2785-00 RevA System Controller + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "ZynqMP System Controller on vp-x-a2785-00 board RevA"; + compatible = "xlnx,zynqmp-vp-x-a2785-00-revA", + "xlnx,zynqmp-vp-x-a2785-00", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + usb1 = &usb1; + nvmem0 = &eeprom; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + key-j383 { + label = "j383"; + gpios = <&gpio 10 GPIO_ACTIVE_HIGH>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { /* ds52 */ + label = "heartbeat"; + gpios = <&gpio 9 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + si5332_0: si5332-0 { /* ps_ref_clk - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; + }; + + si5332_1: si5332-1 { /* clk0_sgmii - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; /* FIXME */ + }; + + si5332_2: si5332-2 { /* clk1_usb - u142 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; +}; + +&qspi { /* MIO 0-5 */ + status = "okay"; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* u285 - mt25qu512abb8e12 512Mib */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-tx-bus-width = <4>; /* maybe 4 here */ + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + partition@0 { /* for testing purpose */ + label = "qspi"; + reg = <0 0x4000000>; + }; + }; +}; + +&sdhci1 { /* sd MIO 45-51 */ + status = "okay"; + no-1-8-v; + disable-wp; + xlnx,mio-bank = <1>; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; + bootph-all; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; /* DTG generates this properly 1512 */ + is-internal-pcspma; + /* phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; */ + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + /* reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; */ + phy0: ethernet-phy@0 { /* u131 - M88e1512 */ + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "QSPI_CLK", "QSPI_DQ1", "QSPI_DQ2", "QSPI_DQ3", "QSPI_DQ0", /* 0 - 4 */ + "QSPI_CS_B", "", "", "SYSCTLR_GPIO", "SYSCTLR_LED", /* 5 - 9 */ + "SYSCTLR_PB", "PMC_ZU4_TRIGGER", "", "", "", /* 10 - 14 */ + "", "", "", "", "", /* 15 - 19 */ + "", "", "", "", "", /* 20 - 24 */ + "", "", "", "", "", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "", "", "ETH_RESET_B", "", "", /* 40 - 44 */ + "SD1_CD", "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", /* 45 - 49 */ + "SD1_CMD", "SD1_CLK", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "", /* 60 - 64 */ + "", "", "", "", "", /* 65 - 69 */ + "", "", "", "", "", /* 70 - 74 */ + "", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 - 89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 34 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 35 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + tca6416_u233: gpio@20 { /* u233 */ /* FIXME - address maybe wrong */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "", "", /* 0 - 3 */ + "", "", "", "MAX6643_FULL_SPEED", /* 4 - 7 */ + "", "", "", "VCCINT_FAULT_B", /* 10 - 13 */ + "VCCINT_VRHOT_B", "", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + reg_vccint: tps53681@60 { /* u266 - 0xc0 */ + compatible = "ti,tps53681", "ti,tps53679"; + reg = <0x60>; + }; + reg_vcc1v1_lp4: tps544@d { /* u85 */ + compatible = "ti,tps544b25"; + reg = <0xd>; + }; + reg_mgtyavcc: tps544@10 { /* u274 */ + compatible = "ti,tps544b25"; + reg = <0x10>; + }; + reg_mgtyavtt: tps544@11 { /* u275 */ + compatible = "ti,tps544b25"; + reg = <0x11>; + }; + reg_vccaux: tps544@12 { /* u276 */ + compatible = "ti,tps544b25"; + reg = <0x12>; + }; + reg_vcc_cpm: tps544@14 { /* u272 */ + compatible = "ti,tps544b25"; + reg = <0x14>; + }; + reg_util_3v3: tps544@1d { /* u278 */ + compatible = "ti,tps544b25"; + reg = <0x1d>; + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vcc_cpm: ina226@44 { /* u273 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <1000>; + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pcie_smbus: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + pcie2_smbus: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + i2c@5 { /* NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + user_si570: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + }; + /* 7 unused */ + }; +}; + +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 36 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 37 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + dc_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* & 0x5c */ + }; + si570_ref_clk: clock-generator@5d { /* u32 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "ref_clk"; + silabs,skip-recall; + }; + }; + i2c@1 { /* NC - FIXME */ + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + i2c@2 { /* NC - FIXME */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + i2c@3 { /* NC - FIXME */ + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + }; + lpddr4_si570_clk2_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + lpddr4_clk2: clock-generator@60 { /* u3 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk2"; + }; + }; + lpddr4_si570_clk1_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + lpddr4_clk1: clock-generator@60 { /* u248 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk1"; + }; + }; + /* 6-7 unused */ + }; +}; + +&usb0 { /* MIO52 - MIO63 */ + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 1 PHY_TYPE_USB3 0 1>; +}; + +&psgtr { + status = "okay"; + /* sgmii, usb3 */ + clocks = <&si5332_1>, <&si5332_2>; + clock-names = "ref0", "ref1"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "peripheral"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + maximum-speed = "super-speed"; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; + +&pinctrl0 { + status = "okay"; + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_8_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_8_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_34_grp", "gpio0_35_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_34_grp", "gpio0_35_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_9_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_9_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + mux { + groups = "gpio0_36_grp", "gpio0_37_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_36_grp", "gpio0_37_grp"; + slew-rate = ; + power-source = ; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-vpk120-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-vpk120-revA.dts @@ -0,0 +1,611 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP VPK120 RevA System Controller + * + * (C) Copyright 2021 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "ZynqMP System Controller on VPK120 board RevA"; + compatible = "xlnx,zynqmp-vpk120-revA", + "xlnx,zynqmp-vpk120", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem0; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci0; + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + usb1 = &usb1; + nvmem0 = &eeprom; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + si570_user1_fmc_clk: si570-user1-fmc-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&user_si570_1>; + }; + + si570_ref_clk: si570-ref-clk { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&ref_clk>; + }; + + si570_lpddr4_clk3: si570-lpddr4-clk3 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk3>; + }; + + si570_lpddr4_clk2: si570-lpddr4-clk2 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk2>; + }; + + si570_lpddr4_clk1: si570-lpddr4-clk1 { + status = "okay"; + compatible = "xlnx,fclk"; + clocks = <&lpddr4_clk1>; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + button-16 { + label = "sw16"; + gpios = <&gpio 10 GPIO_ACTIVE_HIGH>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { /* ds40 */ + label = "heartbeat"; + gpios = <&gpio 9 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + si5332_0: si5332-0 { /* ps_ref_clk */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; + }; + + si5332_1: si5332-1 { /* clk0_sgmii */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <33333333>; /* FIXME */ + }; + + si5332_2: si5332-2 { /* clk1_usb */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; +}; + +&qspi { /* MIO 0-5 */ + status = "okay"; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* mt25qu512abb8e12 512Mib */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <108000000>; + partition@0 { /* for testing purpose */ + label = "qspi"; + reg = <0 0x4000000>; + }; + }; +}; + +&sdhci0 { /* emmc MIO 13-23 - with some settings MTFC16GAPALBH 16GB */ + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + xlnx,mio-bank = <0>; +}; + +&uart0 { /* uart0 MIO38-39 */ + status = "okay"; + bootph-all; +}; + +&gem0 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; /* DTG generates this properly 1512 */ + is-internal-pcspma; + /* phys = <&psgtr 0 PHY_TYPE_SGMII 0 0>; */ + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + /* reset-gpios = <&gpio 142 GPIO_ACTIVE_LOW>; */ + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "QSPI_CLK", "QSPI_DQ1", "QSPI_DQ2", "QSPI_DQ3", "QSPI_DQ0", /* 0 - 4 */ + "QSPI_CS_B", "", "", "SYSCTLR_GPIO", "SYSCTLR_LED", /* 5 - 9 */ + "SYSCTLR_PB", "PMC_ZU4_TRIGGER", "", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */ + "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */ + "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST_B", "", /* 20 - 24 */ + "", "", "", "", "", /* 25 - 29 */ + "", "", "", "", "LP_I2C0_PMC_SCL", /* 30 - 34 */ + "LP_I2C0_PMC_SDA", "LP_I2C1_SCL", "LP_I2C1_SDA", "UART0_RXD_IN", "UART0_TXD_OUT", /* 35 - 39 */ + "", "", "ETH_RESET_B", "", "", /* 40 - 44 */ + "", "", "", "", "", /* 45 - 49 */ + "", "", "USB0_CLK", "USB0_DIR", "USB0_DATA2", /* 50 - 54 */ + "USB0_NXT", "USB0_DATA0", "USB0_DATA1", "USB0_STP", "USB0_DATA3", /* 55 - 59 */ + "USB0_DATA4", "USB0_DATA5", "USB0_DATA6", "USB0_DATA7", "", /* 60 - 64 */ + "", "", "", "", "", /* 65 - 69 */ + "", "", "", "", "", /* 70 - 74 */ + "", "ETH_MDC", "ETH_MDIO", /* 75 - 77, MIO end and EMIO start */ + "SYSCTLR_VERSAL_MODE0", "SYSCTLR_VERSAL_MODE1", /* 78 - 79 */ + "SYSCTLR_VERSAL_MODE2", "SYSCTLR_VERSAL_MODE3", "SYSCTLR_POR_B_LS", "", "", /* 80 - 84 */ + "SYSCTLR_JTAG_S0", "SYSCTLR_JTAG_S1", "SYSCTLR_IIC_MUX0_RESET_B", "SYSCTLR_IIC_MUX1_RESET_B", "", /* 85 - 89 */ + "SYSCTLR_GPIO0", "SYSCTLR_GPIO1", "SYSCTLR_GPIO2", "SYSCTLR_GPIO3", "SYSCTLR_GPIO4", /* 90 - 94 */ + "SYSCTLR_GPIO5", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { /* MIO 34-35 - can't stay here */ + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 34 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 35 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + tca6416_u233: gpio@20 { /* u233 */ /* FIXME - address maybe wrong */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "QSFPDD1_MODSELL", "QSFPDD1_MODSELL", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "MAX6643_FULL_SPEED", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "", "FMCP1_FMCP_PRSNT_M2C_B", "", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@74 { /* u33 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + pmbus_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* On connector J325 */ + ir38060_41: regulator@41 { /* IR38060 - u259 */ + compatible = "infineon,ir38060", "infineon,ir38064"; + reg = <0x41>; /* i2c addr 0x11 */ + }; + ir38164_43: regulator@43 { /* IR38164 - u13 */ + compatible = "infineon,ir38164"; + reg = <0x43>; /* i2c addr 0x13 */ + }; + ir35221_45: pmic@46 { /* IR35221 - u152 */ + compatible = "infineon,ir35221"; + reg = <0x46>; /* PMBUS - 0x16 */ + }; + irps5401_47: pmic5401@47 { /* IRPS5401 - u160 */ + compatible = "infineon,irps5401"; + reg = <0x47>; /* i2c addr 0x17 */ + }; + ir38164_49: regulator@49 { /* IR38164 - u189 */ + compatible = "infineon,ir38164"; + reg = <0x49>; /* i2c addr 0x19 */ + }; + irps5401_4c: pmic@4c { /* IRPS5401 - u167 */ + compatible = "infineon,irps5401"; + reg = <0x4c>; /* i2c addr 0x1c */ + }; + irps5401_4d: pmic@4d { /* IRPS5401 - u175 */ + compatible = "infineon,irps5401"; + reg = <0x4d>; /* i2c addr 0x1c */ + }; + ir38164_4e: regulator@4e { /* IR38164 - u184 */ + compatible = "infineon,ir38164"; + reg = <0x4e>; /* i2c addr 0x1e */ + }; + ir38164_4f: regulator@4f { /* IR38164 - u187 */ + compatible = "infineon,ir38164"; + reg = <0x4f>; /* i2c addr 0x1f */ + }; + }; + pmbus1_ina226_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME check alerts coming to SC */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vcc_soc: ina226@41 { /* u161 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcc_pmc: ina226@42 { /* u163 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc_ram: ina226@43 { /* u5 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcc_pslp: ina226@44 { /* u165 */ + compatible = "ti,ina226"; + reg = <0x44>; + shunt-resistor = <5000>; + }; + vcc_psfp: ina226@45 { /* u164 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + }; + i2c@2 { /* NC */ /* FIXME maybe remove */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + pmbus2_ina226_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* FIXME check alerts coming to SC */ + vccaux: ina226@40 { /* u166 */ + compatible = "ti,ina226"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccaux_pmc: ina226@41 { /* u168 */ + compatible = "ti,ina226"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + mgtavcc: ina226@42 { /* u265 */ + compatible = "ti,ina226"; + reg = <0x42>; + shunt-resistor = <5000>; + }; + vcc1v5: ina226@43 { /* u264 */ + compatible = "ti,ina226"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vcco_mio: ina226@45 { /* u172 */ + compatible = "ti,ina226"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + mgtavtt: ina226@46 { /* u188 */ + compatible = "ti,ina226"; + reg = <0x46>; + shunt-resistor = <2000>; + }; + vcco_502: ina226@47 { /* u174 */ + compatible = "ti,ina226"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + mgtvccaux: ina226@48 { /* u176 */ + compatible = "ti,ina226"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vcc1v1_lp4: ina226@49 { /* u186 */ + compatible = "ti,ina226"; + reg = <0x49>; + shunt-resistor = <2000>; + }; + vadj_fmc: ina226@4a { /* u184 */ + compatible = "ti,ina226"; + reg = <0x4a>; + shunt-resistor = <2000>; + }; + lpdmgtyavcc: ina226@4b { /* u177 */ + compatible = "ti,ina226"; + reg = <0x4b>; + shunt-resistor = <5000>; + }; + lpdmgtyavtt: ina226@4c { /* u260 */ + compatible = "ti,ina226"; + reg = <0x4c>; + shunt-resistor = <2000>; + }; + lpdmgtyvccaux: ina226@4d { /* u234 */ + compatible = "ti,ina226"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + }; + i2c@4 { /* NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + }; + i2c@5 { /* NC */ + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + }; + user_si570: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + user_si570_1: clock-generator@5f { /* USER C0 SI570 - u205 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5f>; + temperature-stability = <50>; + factory-fout = <100000000>; + clock-frequency = <100000000>; + clock-output-names = "fmc_si570"; + }; + + }; + /* 7 unused */ + }; +}; + +&i2c1 { /* i2c1 MIO 36-37 */ + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 36 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 37 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + i2c-mux@74 { /* u35 */ + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* reset-gpios = <&gpio SYSCTLR_IIC_MUX1_RESET_B GPIO_ACTIVE_HIGH>; */ + ref_clk_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* Use for storing information about SC board */ + eeprom: eeprom@54 { /* u34 - m24128 16kB */ + compatible = "st,24c128", "atmel,24c128"; + reg = <0x54>; /* & 0x5c */ + }; + ref_clk: clock-generator@5d { /* u32 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "ref_clk"; + silabs,skip-recall; + }; + }; + fmcp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* FIXME connection to Samtec J51C */ + /* expected eeprom 0x50 SE cards */ + }; + i2c@2 { /* NC - FIXME */ + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + lpddr4_si570_clk3_i2c: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + lpddr4_clk3: clock-generator@60 { /* u4 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk3"; + }; + }; + lpddr4_si570_clk2_i2c: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + lpddr4_clk2: clock-generator@60 { /* u3 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk2"; + }; + }; + lpddr4_si570_clk1_i2c: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + lpddr4_clk1: clock-generator@60 { /* u248 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x60>; + temperature-stability = <50>; + factory-fout = <200000000>; + clock-frequency = <200000000>; + clock-output-names = "lpddr4_clk1"; + }; + }; + qsfpdd_i2c: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* J1/J2 connectors */ + }; + idt8a34001_i2c: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* Via J310 connector */ + idt_8a34001: phc@5b { + compatible = "idt,8a34001"; /* u219B */ + reg = <0x5b>; /* FIXME not in schematics */ + }; + }; + }; +}; + +&usb0 { /* MIO52 - MIO63 */ + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 1 PHY_TYPE_USB3 0 1>; +}; + +&psgtr { + status = "okay"; + /* sgmii, usb3 */ + clocks = <&si5332_1>, <&si5332_2>; + clock-names = "ref0", "ref1"; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "peripheral"; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + maximum-speed = "super-speed"; +}; + +&xilinx_ams { + status = "okay"; +}; + +&ams_ps { + status = "okay"; +}; + +&ams_pl { + status = "okay"; +}; + +&pinctrl0 { + status = "okay"; + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_8_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_8_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_34_grp", "gpio0_35_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_34_grp", "gpio0_35_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_9_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_9_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + mux { + groups = "gpio0_36_grp", "gpio0_37_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_36_grp", "gpio0_37_grp"; + slew-rate = ; + power-source = ; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts @@ -40,13 +40,29 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB FIXME */ #address-cells = <1>; #size-cells = <1>; reg = <0x0>; spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts @@ -48,6 +48,22 @@ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts @@ -148,7 +148,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_36_grp", "gpio0_37_grp"; function = "gpio0"; @@ -354,14 +354,32 @@ &qspi { status = "okay"; + num-cs = <2>; flash@0 { compatible = "m25p80", "jedec,spi-nor"; /* Micron MT25QU512ABB8ESF */ #address-cells = <1>; #size-cells = <1>; - reg = <0x0>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts @@ -141,19 +141,73 @@ reg = <0x0>; #address-cells = <0x2>; #size-cells = <0x1>; - nand-ecc-mode = "soft"; - nand-ecc-algo = "bch"; + nand-ecc-mode = "hw"; nand-rb = <0>; label = "main-storage-0"; + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-on-flash-bbt; + + partition@0 { /* for testing purpose */ + label = "nand-fsbl-uboot"; + reg = <0x0 0x0 0x400000>; + }; + partition@1 { /* for testing purpose */ + label = "nand-linux"; + reg = <0x0 0x400000 0x1400000>; + }; + partition@2 { /* for testing purpose */ + label = "nand-device-tree"; + reg = <0x0 0x1800000 0x400000>; + }; + partition@3 { /* for testing purpose */ + label = "nand-rootfs"; + reg = <0x0 0x1c00000 0x1400000>; + }; + partition@4 { /* for testing purpose */ + label = "nand-bitstream"; + reg = <0x0 0x3000000 0x400000>; + }; + partition@5 { /* for testing purpose */ + label = "nand-misc"; + reg = <0x0 0x3400000 0xfcc00000>; + }; }; nand@1 { reg = <0x1>; #address-cells = <0x2>; #size-cells = <0x1>; - nand-ecc-mode = "soft"; - nand-ecc-algo = "bch"; + nand-ecc-mode = "hw"; nand-rb = <0>; label = "main-storage-1"; + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-on-flash-bbt; + + partition@0 { /* for testing purpose */ + label = "nand1-fsbl-uboot"; + reg = <0x0 0x0 0x400000>; + }; + partition@1 { /* for testing purpose */ + label = "nand1-linux"; + reg = <0x0 0x400000 0x1400000>; + }; + partition@2 { /* for testing purpose */ + label = "nand1-device-tree"; + reg = <0x0 0x1800000 0x400000>; + }; + partition@3 { /* for testing purpose */ + label = "nand1-rootfs"; + reg = <0x0 0x1c00000 0x1400000>; + }; + partition@4 { /* for testing purpose */ + label = "nand1-bitstream"; + reg = <0x0 0x3000000 0x400000>; + }; + partition@5 { /* for testing purpose */ + label = "nand1-misc"; + reg = <0x0 0x3400000 0xfcc00000>; + }; }; }; @@ -219,7 +273,7 @@ }; }; - pinctrl_i2c0_gpio: i2c0-gpio { + pinctrl_i2c0_gpio: i2c0-gpio-grp { mux { groups = "gpio0_6_grp", "gpio0_7_grp"; function = "gpio0"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts @@ -131,6 +131,79 @@ status = "okay"; arasan,has-mdma; num-cs = <2>; + + nand@0 { + reg = <0x0>; + #address-cells = <0x2>; + #size-cells = <0x1>; + nand-ecc-mode = "hw"; + nand-rb = <0>; + label = "main-storage-0"; + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-on-flash-bbt; + + partition@0 { /* for testing purpose */ + label = "nand-fsbl-uboot"; + reg = <0x0 0x0 0x400000>; + }; + partition@1 { /* for testing purpose */ + label = "nand-linux"; + reg = <0x0 0x400000 0x1400000>; + }; + partition@2 { /* for testing purpose */ + label = "nand-device-tree"; + reg = <0x0 0x1800000 0x400000>; + }; + partition@3 { /* for testing purpose */ + label = "nand-rootfs"; + reg = <0x0 0x1C00000 0x1400000>; + }; + partition@4 { /* for testing purpose */ + label = "nand-bitstream"; + reg = <0x0 0x3000000 0x400000>; + }; + partition@5 { /* for testing purpose */ + label = "nand-misc"; + reg = <0x0 0x3400000 0xFCC00000>; + }; + }; + nand@1 { + reg = <0x1>; + #address-cells = <0x2>; + #size-cells = <0x1>; + nand-ecc-mode = "hw"; + nand-rb = <0>; + label = "main-storage-1"; + nand-ecc-step-size = <1024>; + nand-ecc-strength = <24>; + nand-on-flash-bbt; + + partition@0 { /* for testing purpose */ + label = "nand1-fsbl-uboot"; + reg = <0x0 0x0 0x400000>; + }; + partition@1 { /* for testing purpose */ + label = "nand1-linux"; + reg = <0x0 0x400000 0x1400000>; + }; + partition@2 { /* for testing purpose */ + label = "nand1-device-tree"; + reg = <0x0 0x1800000 0x400000>; + }; + partition@3 { /* for testing purpose */ + label = "nand1-rootfs"; + reg = <0x0 0x1C00000 0x1400000>; + }; + partition@4 { /* for testing purpose */ + label = "nand1-bitstream"; + reg = <0x0 0x3000000 0x400000>; + }; + partition@5 { /* for testing purpose */ + label = "nand1-misc"; + reg = <0x0 0x3400000 0xFCC00000>; + }; + }; }; &psgtr { --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts @@ -180,6 +180,22 @@ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; /* also DUAL configuration possible */ spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts @@ -125,7 +125,7 @@ }; }; - pinctrl_i2c0_gpio: i2c0-gpio { + pinctrl_i2c0_gpio: i2c0-gpio-grp { mux { groups = "gpio0_74_grp", "gpio0_75_grp"; function = "gpio0"; @@ -152,7 +152,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_76_grp", "gpio0_77_grp"; function = "gpio0"; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts @@ -275,7 +275,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_4_grp", "gpio0_5_grp"; function = "gpio0"; @@ -509,6 +509,9 @@ xlnx,mio-bank = <0>; non-removable; disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; cap-power-off-card; mmc-pwrseq = <&sdio_pwrseq>; vqmmc-supply = <&wmmcsdio_fixed>; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts @@ -603,7 +603,7 @@ reg = <0x5d>; temperature-stability = <50>; /* copy from zc702 */ factory-fout = <156250000>; - clock-frequency = <148500000>; + clock-frequency = <156250000>; clock-output-names = "si570_mgt"; }; }; @@ -611,7 +611,26 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - /* SI5328 - u20 */ + si5328: clock-generator@69 {/* SI5328 - u20 */ + compatible = "silabs,si5328"; + reg = <0x69>; + /* + * Chip has interrupt present connected to PL + * interrupt-parent = <&>; + * interrupts = <>; + */ + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + clocks = <&refhdmi>; + clock-names = "xtal"; + clock-output-names = "si5328"; + + si5328_clk: clk0@0 { + reg = <0>; + clock-frequency = <27000000>; + }; + }; }; /* 5 - 7 unconnected */ }; @@ -689,7 +708,7 @@ }; }; - pinctrl_i2c0_gpio: i2c0-gpio { + pinctrl_i2c0_gpio: i2c0-gpio-grp { mux { groups = "gpio0_14_grp", "gpio0_15_grp"; function = "gpio0"; @@ -716,7 +735,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_16_grp", "gpio0_17_grp"; function = "gpio0"; @@ -952,14 +971,32 @@ &qspi { status = "okay"; + num-cs = <2>; flash@0 { - compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; - reg = <0x0>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts @@ -272,7 +272,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_16_grp", "gpio0_17_grp"; function = "gpio0"; @@ -447,6 +447,22 @@ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts @@ -284,7 +284,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_16_grp", "gpio0_17_grp"; function = "gpio0"; @@ -459,6 +459,22 @@ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts @@ -152,17 +152,6 @@ clock-frequency = <114285000>; }; - dpcon { - compatible = "dp-connector"; - label = "P11"; - type = "full-size"; - - port { - dpcon_in: endpoint { - remote-endpoint = <&dpsub_dp_out>; - }; - }; - }; }; &can1 { @@ -605,7 +594,7 @@ reg = <0x5d>; temperature-stability = <50>; /* copy from zc702 */ factory-fout = <156250000>; - clock-frequency = <148500000>; + clock-frequency = <156250000>; clock-output-names = "si570_mgt"; }; }; @@ -613,7 +602,26 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - /* SI5328 - u20 */ + si5328: clock-generator@69 {/* SI5328 - u20 */ + compatible = "silabs,si5328"; + reg = <0x69>; + /* + * Chip has interrupt present connected to PL + * interrupt-parent = <&>; + * interrupts = <>; + */ + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + clocks = <&refhdmi>; + clock-names = "xtal"; + clock-output-names = "si5328"; + + si5328_clk: clk0@0 { + reg = <0>; + clock-frequency = <27000000>; + }; + }; }; i2c@5 { #address-cells = <1>; @@ -700,7 +708,7 @@ }; }; - pinctrl_i2c0_gpio: i2c0-gpio { + pinctrl_i2c0_gpio: i2c0-gpio-grp { mux { groups = "gpio0_14_grp", "gpio0_15_grp"; function = "gpio0"; @@ -727,7 +735,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_16_grp", "gpio0_17_grp"; function = "gpio0"; @@ -959,14 +967,32 @@ &qspi { status = "okay"; + num-cs = <2>; flash@0 { - compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; - reg = <0x0>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x4000000 0x4000000>; /* 64MB */ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; @@ -1042,12 +1068,4 @@ phy-names = "dp-phy0", "dp-phy1"; phys = <&psgtr 1 PHY_TYPE_DP 0 3>, <&psgtr 0 PHY_TYPE_DP 1 3>; - - ports { - port@5 { - dpsub_dp_out: endpoint { - remote-endpoint = <&dpcon_in>; - }; - }; - }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts @@ -589,7 +589,7 @@ }; }; - pinctrl_i2c0_gpio: i2c0-gpio { + pinctrl_i2c0_gpio: i2c0-gpio-grp { mux { groups = "gpio0_14_grp", "gpio0_15_grp"; function = "gpio0"; @@ -616,7 +616,7 @@ }; }; - pinctrl_i2c1_gpio: i2c1-gpio { + pinctrl_i2c1_gpio: i2c1-gpio-grp { mux { groups = "gpio0_16_grp", "gpio0_17_grp"; function = "gpio0"; @@ -789,14 +789,32 @@ &qspi { status = "okay"; + num-cs = <2>; flash@0 { - compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */ + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ #address-cells = <1>; #size-cells = <1>; - reg = <0x0>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x10000000 0x10000000>; /* 256MB */ spi-tx-bus-width = <4>; spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * dts file for Xilinx ZynqMP ZC1275 + * dts file for Xilinx ZynqMP ZCU1275 * * (C) Copyright 2017 - 2021, Xilinx, Inc. * @@ -15,7 +15,8 @@ / { model = "ZynqMP ZCU1275 RevA"; - compatible = "xlnx,zynqmp-zcu1275-revA", "xlnx,zynqmp-zcu1275", "xlnx,zynqmp"; + compatible = "xlnx,zynqmp-zcu1275-revA", "xlnx,zynqmp-zcu1275", + "xlnx,zynqmp"; aliases { serial0 = &uart0; @@ -45,11 +46,29 @@ &qspi { status = "okay"; flash@0 { - compatible = "m25p80", "jedec,spi-nor"; + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + #address-cells = <1>; + #size-cells = <1>; reg = <0x0>; spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - spi-max-frequency = <108000000>; + spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; }; }; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revB.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revB.dts @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP ZCU1275 RevB + * + * (C) Copyright 2018 - 2021, Xilinx, Inc. + * + * Michal Simek + * Siva Durga Prasad Paladugu + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" + +/ { + model = "ZynqMP ZCU1275 RevB"; + compatible = "xlnx,zynqmp-zcu1275-revB", "xlnx,zynqmp-zcu1275", + "xlnx,zynqmp"; + + aliases { + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + mmc0 = &sdhci1; + ethernet0 = &gem1; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; + +&dcc { + status = "okay"; +}; + +&gem1 { + status = "okay"; + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: ethernet-phy@1 { + reg = <1>; /* KSZ9031RNXIC on AES-FMC-NETW1-G */ + rxc-skew-ps = <1800>; /* Skew control of RX_CLK pad output */ + txc-skew-ps = <1800>; /* Skew control of GTX_CLK pad input */ + txen-skew-ps = <900>; /* Skew control of TX_CTL pad input */ + rxdv-skew-ps = <0>; /* Skew control of RX_CTL pad output */ + rxd0-skew-ps = <0>; /* Skew control of RXD0 pad output */ + rxd1-skew-ps = <0>; /* Skew control of RXD1 pad output */ + rxd2-skew-ps = <0>; /* Skew control of RXD2 pad output */ + rxd3-skew-ps = <0>; /* Skew control of RXD3 pad output */ + txd0-skew-ps = <900>; /* Skew control of TXD0 pad input */ + txd1-skew-ps = <900>; /* Skew control of TXD1 pad input */ + txd2-skew-ps = <900>; /* Skew control of TXD2 pad input */ + txd3-skew-ps = <900>; /* Skew control of TXD3 pad input */ + }; + }; +}; + +&gpio { + status = "okay"; +}; + +&qspi { + status = "okay"; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + partition@0 { /* for testing purpose */ + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; + }; + partition@100000 { /* for testing purpose */ + label = "qspi-linux"; + reg = <0x100000 0x500000>; + }; + partition@600000 { /* for testing purpose */ + label = "qspi-device-tree"; + reg = <0x600000 0x20000>; + }; + partition@620000 { /* for testing purpose */ + label = "qspi-rootfs"; + reg = <0x620000 0x5E0000>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; + /* + * 1.0 revision has level shifter and this property should be + * removed for supporting UHS mode + */ + no-1-8-v; + xlnx,mio-bank = <1>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu1285-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu1285-revA.dts @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP ZCU1285 RevA + * + * (C) Copyright 2018 - 2021, Xilinx, Inc. + * + * Michal Simek + * Siva Durga Prasad Paladugu + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" + +/ { + model = "ZynqMP ZCU1285 RevA"; + compatible = "xlnx,zynqmp-zcu1285-revA", "xlnx,zynqmp-zcu1285", + "xlnx,zynqmp"; + + aliases { + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + mmc0 = &sdhci1; + ethernet0 = &gem1; /* EMIO */ + i2c = &i2c0; /* EMIO */ + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + +}; + +&dcc { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + +}; + +&gem1 { + mdio { + #address-cells = <1>; + #size-cells = <0>; + phy1: ethernet-phy@1 { + reg = <1>; /* KSZ9031RNXIC on AES-FMC-NETW1-G */ + rxc-skew-ps = <1800>; /* Skew control of RX_CLK pad output */ + txc-skew-ps = <1800>; /* Skew control of GTX_CLK pad input */ + txen-skew-ps = <900>; /* Skew control of TX_CTL pad input */ + rxdv-skew-ps = <0>; /* Skew control of RX_CTL pad output */ + rxd0-skew-ps = <0>; /* Skew control of RXD0 pad output */ + rxd1-skew-ps = <0>; /* Skew control of RXD1 pad output */ + rxd2-skew-ps = <0>; /* Skew control of RXD2 pad output */ + rxd3-skew-ps = <0>; /* Skew control of RXD3 pad output */ + txd0-skew-ps = <900>; /* Skew control of TXD0 pad input */ + txd1-skew-ps = <900>; /* Skew control of TXD1 pad input */ + txd2-skew-ps = <900>; /* Skew control of TXD2 pad input */ + txd3-skew-ps = <900>; /* Skew control of TXD3 pad input */ + }; + }; +}; + +&gpio { + status = "okay"; +}; + +&qspi { + status = "okay"; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* 32MB */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + }; +}; + +&uart0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; + /* + * This property should be removed for supporting UHS mode + */ + no-1-8-v; + xlnx,mio-bank = <1>; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu208-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu208-revA.dts @@ -0,0 +1,712 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * dts file for Xilinx ZynqMP ZCU208 + * + * (C) Copyright 2017 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "ZynqMP ZCU208 RevA"; + compatible = "xlnx,zynqmp-zcu208-revA", "xlnx,zynqmp-zcu208", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + switch-19 { + label = "sw19"; + gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { + label = "heartbeat"; + gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + ina226-vccint { + compatible = "iio-hwmon"; + io-channels = <&vccint 0>, <&vccint 1>, <&vccint 2>, <&vccint 3>; + }; + ina226-vccint-io-bram-ps { + compatible = "iio-hwmon"; + io-channels = <&vccint_io_bram_ps 0>, <&vccint_io_bram_ps 1>, <&vccint_io_bram_ps 2>, <&vccint_io_bram_ps 3>; + }; + ina226-vcc1v8 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v8 0>, <&vcc1v8 1>, <&vcc1v8 2>, <&vcc1v8 3>; + }; + ina226-vcc1v2 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2 0>, <&vcc1v2 1>, <&vcc1v2 2>, <&vcc1v2 3>; + }; + ina226-vadj-fmc { + compatible = "iio-hwmon"; + io-channels = <&vadj_fmc 0>, <&vadj_fmc 1>, <&vadj_fmc 2>, <&vadj_fmc 3>; + }; + ina226-mgtavcc { + compatible = "iio-hwmon"; + io-channels = <&mgtavcc 0>, <&mgtavcc 1>, <&mgtavcc 2>, <&mgtavcc 3>; + }; + ina226-mgt1v2 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v2 0>, <&mgt1v2 1>, <&mgt1v2 2>, <&mgt1v2 3>; + }; + ina226-mgt1v8 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v8 0>, <&mgt1v8 1>, <&mgt1v8 2>, <&mgt1v8 3>; + }; + ina226-vccint-ams { + compatible = "iio-hwmon"; + io-channels = <&vccint_ams 0>, <&vccint_ams 1>, <&vccint_ams 2>, <&vccint_ams 3>; + }; + ina226-dac-avtt { + compatible = "iio-hwmon"; + io-channels = <&dac_avtt 0>, <&dac_avtt 1>, <&dac_avtt 2>, <&dac_avtt 3>; + }; + ina226-dac-avccaux { + compatible = "iio-hwmon"; + io-channels = <&dac_avccaux 0>, <&dac_avccaux 1>, <&dac_avccaux 2>, <&dac_avccaux 3>; + }; + ina226-adc-avcc { + compatible = "iio-hwmon"; + io-channels = <&adc_avcc 0>, <&adc_avcc 1>, <&adc_avcc 2>, <&adc_avcc 3>; + }; + ina226-adc-avccaux { + compatible = "iio-hwmon"; + io-channels = <&adc_avccaux 0>, <&adc_avccaux 1>, <&adc_avccaux 2>, <&adc_avccaux 3>; + }; + ina226-dac-avcc { + compatible = "iio-hwmon"; + io-channels = <&dac_avcc 0>, <&dac_avcc 1>, <&dac_avcc 2>, <&dac_avcc 3>; + }; + + /* 48MHz reference crystal */ + ref48: ref48M { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + }; +}; + +&dcc { + status = "okay"; +}; + +&fpd_dma_chan1 { + status = "okay"; +}; + +&fpd_dma_chan2 { + status = "okay"; +}; + +&fpd_dma_chan3 { + status = "okay"; +}; + +&fpd_dma_chan4 { + status = "okay"; +}; + +&fpd_dma_chan5 { + status = "okay"; +}; + +&fpd_dma_chan6 { + status = "okay"; +}; + +&fpd_dma_chan7 { + status = "okay"; +}; + +&fpd_dma_chan8 { + status = "okay"; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "QSPI_LWR_CLK", "QSPI_LWR_DQ1", "QSPI_LWR_DQ2", "QSPI_LWR_DQ3", "QSPI_LWR_DQ0", /* 0 - 4 */ + "QSPI_LWR_CS_B", "", "QSPI_UPR_CS_B", "QSPI_UPR_DQ0", "QSPI_UPR_DQ1", /* 5 - 9 */ + "QSPI_UPR_DQ2", "QSPI_UPR_DQ3", "QSPI_UPR_CLK", "PS_GPIO2", "I2C0_SCL", /* 10 - 14 */ + "I2C0_SDA", "I2C1_SCL", "I2C1_SDA", "UART0_TXD", "UART0_RXD", /* 15 - 19 */ + "", "", "BUTTON", "LED", "", /* 20 - 24 */ + "", "PMU_INPUT", "", "", "", /* 25 - 29 */ + "", "", "PMU_GPO0", "PMU_GPO1", "PMU_GPO2", /* 30 - 34 */ + "PMU_GPO3", "PMU_GPO4", "PMU_GPO5", "PS_GPIO1", "SDIO_SEL", /* 35 - 39 */ + "SDIO_DIR_CMD", "SDIO_DIR_DAT0", "SDIO_DIR_DAT1", "", "", /* 40 - 44 */ + "SDIO_DETECT", "SDIO_DAT0", "SDIO_DAT1", "SDIO_DAT2", "SDIO_DAT3", /* 45 - 49 */ + "SDIO_CMD", "SDIO_CLK", "USB_CLK", "USB_DIR", "USB_DATA2", /* 50 - 54 */ + "USB_NXT", "USB_DATA0", "USB_DATA1", "USB_STP", "USB_DATA3", /* 55 - 59 */ + "USB_DATA4", "USB_DATA5", "USB_DATA6", "USB_DATA7", "ENET_TX_CLK", /* 60 - 64 */ + "ENET_TX_D0", "ENET_TX_D1", "ENET_TX_D2", "ENET_TX_D3", "ENET_TX_CTRL", /* 65 - 69 */ + "ENET_RX_CLK", "ENET_RX_D0", "ENET_RX_D1", "ENET_RX_D2", "ENET_RX_D3", /* 70 - 74 */ + "ENET_RX_CTRL", "ENET_MDC", "ENET_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + tca6416_u15: gpio@20 { /* u15 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "MIO26_PMU_INPUT_LS", "DAC_AVTT_VOUT_SEL", /* 0 - 3 */ + "", "IIC_MUX_RESET_B", "GEM3_EXP_RESET_B", "MAX6643_FULL_SPEED", /* 4 - 7 */ + "FMCP_HSPC_PRSNT_M2C_B", "", "", "VCCINT_VRHOT_B", /* 10 - 13 */ + "", "8A34001_EXP_RST_B", "IRPS5401_ALERT_B", "INA226_PMBUS_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@75 { /* u17 */ + compatible = "nxp,pca9544"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* PS_PMBUS */ + /* PMBUS_ALERT done via pca9544 */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccint_io_bram_ps: ina226@41 { /* u57 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-io-bram-ps"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcc1v8: ina226@42 { /* u60 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v8"; + reg = <0x42>; + shunt-resistor = <2000>; + }; + vcc1v2: ina226@43 { /* u58 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vadj_fmc: ina226@45 { /* u62 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vadj-fmc"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + mgtavcc: ina226@46 { /* u67 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtavcc"; + reg = <0x46>; + shunt-resistor = <2000>; + }; + mgt1v2: ina226@47 { /* u63 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v2"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + mgt1v8: ina226@48 { /* u64 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v8"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vccint_ams: ina226@49 { /* u61 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-ams"; + reg = <0x49>; + shunt-resistor = <5000>; + }; + dac_avtt: ina226@4a { /* u59 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avtt"; + reg = <0x4a>; + shunt-resistor = <5000>; + }; + dac_avccaux: ina226@4b { /* u124 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avccaux"; + reg = <0x4b>; + shunt-resistor = <5000>; + }; + adc_avcc: ina226@4c { /* u75 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avcc"; + reg = <0x4c>; + shunt-resistor = <5000>; + }; + adc_avccaux: ina226@4d { /* u71 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avccaux"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + dac_avcc: ina226@4e { /* u77 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avcc"; + reg = <0x4e>; + shunt-resistor = <5000>; + }; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* NC */ + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* u104 - ir35215 0x10/0x40 */ + /* u127 - ir38164 0x1b/0x4b */ + /* u112 - ir38164 0x13/0x43 */ + /* u123 - ir38164 0x1c/0x4c */ + + irps5401_44: irps5401@44 { /* IRPS5401 - u53 */ + compatible = "infineon,irps5401"; + reg = <0x44>; /* i2c addr 0x14 */ + }; + irps5401_45: irps5401@45 { /* IRPS5401 - u55 */ + compatible = "infineon,irps5401"; + reg = <0x45>; /* i2c addr 0x15 */ + }; + /* J21 header too */ + + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* SYSMON */ + }; + }; + /* u38 MPS430 */ +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + i2c-mux@74 { + compatible = "nxp,pca9548"; /* u20 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + i2c-mux-idle-disconnect; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c_eeprom: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* + * IIC_EEPROM 1kB memory which uses 256B blocks + * where every block has different address. + * 0 - 256B address 0x54 + * 256B - 512B address 0x55 + * 512B - 768B address 0x56 + * 768B - 1024B address 0x57 + */ + eeprom: eeprom@54 { /* u21 */ + compatible = "atmel,24c128"; + reg = <0x54>; + }; + }; + i2c_si5341: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + si5341: clock-generator@36 { /* SI5341 - u43 */ + compatible = "silabs,si5341"; + reg = <0x36>; + #clock-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&ref48>; + clock-names = "xtal"; + clock-output-names = "si5341"; + + si5341_2: out@2 { + /* refclk2 for PS-GT, used for USB3 */ + reg = <2>; + always-on; + }; + si5341_3: out@3 { + /* refclk3 for PS-GT, used for SATA */ + reg = <3>; + always-on; + }; + si5341_5: out@5 { + /* refclk5 PL CLK100 */ + reg = <5>; + always-on; + }; + si5341_6: out@6 { + /* refclk6 PL CLK125 */ + reg = <6>; + always-on; + }; + si5341_9: out@9 { + /* refclk9 used for PS_REF_CLK 33.3 MHz */ + reg = <9>; + always-on; + }; + }; + }; + i2c_si570_user_c0: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_1: clock-generator@5d { /* USER C0 SI570 - u47 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; + clock-frequency = <300000000>; + clock-output-names = "si570_user_c0"; + }; + }; + i2c_si570_mgt: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_2: clock-generator@5d { /* USER MGT SI570 - u48 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_mgt"; + }; + }; + i2c_8a34001: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + idt_8a34001: phc@5b { + compatible = "idt,8a34001"; /* u409B */ + reg = <0x5b>; + }; + }; + i2c_clk104: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* CLK104_SDA */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* RFMCP connector */ + }; + /* 7 NC */ + }; + + i2c-mux@75 { + compatible = "nxp,pca9548"; /* u22 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* FMCP_HSPC_IIC */ + }; + i2c_si570_user_c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + si570_3: clock-generator@5d { /* USER C1 SI570 - u130 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; + clock-frequency = <300000000>; + clock-output-names = "si570_user_c1"; + }; + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* SYSMON */ + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* DDR4 SODIMM */ + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* SFP3 */ + }; + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* SFP2 */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* SFP1 */ + }; + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* SFP0 */ + }; + }; + /* MSP430 */ +}; + +&pinctrl0 { + status = "okay"; + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_3_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_3_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_14_grp", "gpio0_15_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_14_grp", "gpio0_15_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_4_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_4_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + mux { + groups = "gpio0_16_grp", "gpio0_17_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_16_grp", "gpio0_17_grp"; + slew-rate = ; + power-source = ; + }; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* U11 and U12 MT25QU02GCBBE12 1Gb */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x10000000 0x10000000>; /* 256MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + }; +}; + +&psgtr { + status = "okay"; + /* nc, nc, usb3, sata */ + clocks = <&si5341 0 2>, <&si5341 0 3>; + clock-names = "ref2", "ref3"; +}; + +&rtc { + status = "okay"; +}; + +&sata { + status = "okay"; + /* SATA OOB timing settings */ + ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + phy-names = "sata-phy"; + phys = <&psgtr 3 PHY_TYPE_SATA 1 3>; +}; + +/* SD1 with level shifter */ +&sdhci1 { + status = "okay"; + disable-wp; + /* + * This property should be removed for supporting UHS mode + */ + no-1-8-v; + xlnx,mio-bank = <1>; +}; + +&uart0 { + status = "okay"; +}; + +/* ULPI SMSC USB3320 */ +&usb0 { + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu216-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu216-revA.dts @@ -0,0 +1,715 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * dts file for Xilinx ZynqMP ZCU216 + * + * (C) Copyright 2017 - 2021, Xilinx, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "ZynqMP ZCU216 RevA"; + compatible = "xlnx,zynqmp-zcu216-revA", "xlnx,zynqmp-zcu216", "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>; + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + switch-19 { + label = "sw19"; + gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { + label = "heartbeat"; + gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + ina226-vccint { + compatible = "iio-hwmon"; + io-channels = <&vccint 0>, <&vccint 1>, <&vccint 2>, <&vccint 3>; + }; + ina226-vccint-io-bram-ps { + compatible = "iio-hwmon"; + io-channels = <&vccint_io_bram_ps 0>, <&vccint_io_bram_ps 1>, <&vccint_io_bram_ps 2>, <&vccint_io_bram_ps 3>; + }; + ina226-vcc1v8 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v8 0>, <&vcc1v8 1>, <&vcc1v8 2>, <&vcc1v8 3>; + }; + ina226-vcc1v2 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2 0>, <&vcc1v2 1>, <&vcc1v2 2>, <&vcc1v2 3>; + }; + ina226-vadj-fmc { + compatible = "iio-hwmon"; + io-channels = <&vadj_fmc 0>, <&vadj_fmc 1>, <&vadj_fmc 2>, <&vadj_fmc 3>; + }; + ina226-mgtavcc { + compatible = "iio-hwmon"; + io-channels = <&mgtavcc 0>, <&mgtavcc 1>, <&mgtavcc 2>, <&mgtavcc 3>; + }; + ina226-mgt1v2 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v2 0>, <&mgt1v2 1>, <&mgt1v2 2>, <&mgt1v2 3>; + }; + ina226-mgt1v8 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v8 0>, <&mgt1v8 1>, <&mgt1v8 2>, <&mgt1v8 3>; + }; + ina226-vccint-ams { + compatible = "iio-hwmon"; + io-channels = <&vccint_ams 0>, <&vccint_ams 1>, <&vccint_ams 2>, <&vccint_ams 3>; + }; + ina226-dac-avtt { + compatible = "iio-hwmon"; + io-channels = <&dac_avtt 0>, <&dac_avtt 1>, <&dac_avtt 2>, <&dac_avtt 3>; + }; + ina226-dac-avccaux { + compatible = "iio-hwmon"; + io-channels = <&dac_avccaux 0>, <&dac_avccaux 1>, <&dac_avccaux 2>, <&dac_avccaux 3>; + }; + ina226-adc-avcc { + compatible = "iio-hwmon"; + io-channels = <&adc_avcc 0>, <&adc_avcc 1>, <&adc_avcc 2>, <&adc_avcc 3>; + }; + ina226-adc-avccaux { + compatible = "iio-hwmon"; + io-channels = <&adc_avccaux 0>, <&adc_avccaux 1>, <&adc_avccaux 2>, <&adc_avccaux 3>; + }; + ina226-dac-avcc { + compatible = "iio-hwmon"; + io-channels = <&dac_avcc 0>, <&dac_avcc 1>, <&dac_avcc 2>, <&dac_avcc 3>; + }; + + /* 48MHz reference crystal */ + ref48: ref48M { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + }; +}; + +&psgtr { + status = "okay"; + /* nc, nc, usb3, sata */ + clocks = <&si5341 0 2>, <&si5341 0 3>; + clock-names = "ref2", "ref3"; +}; + +&dcc { + status = "okay"; +}; + +&fpd_dma_chan1 { + status = "okay"; +}; + +&fpd_dma_chan2 { + status = "okay"; +}; + +&fpd_dma_chan3 { + status = "okay"; +}; + +&fpd_dma_chan4 { + status = "okay"; +}; + +&fpd_dma_chan5 { + status = "okay"; +}; + +&fpd_dma_chan6 { + status = "okay"; +}; + +&fpd_dma_chan7 { + status = "okay"; +}; + +&fpd_dma_chan8 { + status = "okay"; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; + }; + }; +}; +&gpio { + status = "okay"; + gpio-line-names = "QSPI_LWR_CLK", "QSPI_LWR_DQ1", "QSPI_LWR_DQ2", "QSPI_LWR_DQ3", "QSPI_LWR_DQ0", /* 0 - 4 */ + "QSPI_LWR_CS_B", "", "QSPI_UPR_CS_B", "QSPI_UPR_DQ0", "QSPI_UPR_DQ1", /* 5 - 9 */ + "QSPI_UPR_DQ2", "QSPI_UPR_DQ3", "QSPI_UPR_CLK", "PS_GPIO2", "I2C0_SCL", /* 10 - 14 */ + "I2C0_SDA", "I2C1_SCL", "I2C1_SDA", "UART0_TXD", "UART0_RXD", /* 15 - 19 */ + "", "", "BUTTON", "LED", "", /* 20 - 24 */ + "", "PMU_INPUT", "", "", "", /* 25 - 29 */ + "", "", "PMU_GPO0", "PMU_GPO1", "PMU_GPO2", /* 30 - 34 */ + "PMU_GPO3", "PMU_GPO4", "PMU_GPO5", "PS_GPIO1", "SDIO_SEL", /* 35 - 39 */ + "SDIO_DIR_CMD", "SDIO_DIR_DAT0", "SDIO_DIR_DAT1", "", "", /* 40 - 44 */ + "SDIO_DETECT", "SDIO_DAT0", "SDIO_DAT1", "SDIO_DAT2", "SDIO_DAT3", /* 45 - 49 */ + "SDIO_CMD", "SDIO_CLK", "USB_CLK", "USB_DIR", "USB_DATA2", /* 50 - 54 */ + "USB_NXT", "USB_DATA0", "USB_DATA1", "USB_STP", "USB_DATA3", /* 55 - 59 */ + "USB_DATA4", "USB_DATA5", "USB_DATA6", "USB_DATA7", "ENET_TX_CLK", /* 60 - 64 */ + "ENET_TX_D0", "ENET_TX_D1", "ENET_TX_D2", "ENET_TX_D3", "ENET_TX_CTRL", /* 65 - 69 */ + "ENET_RX_CLK", "ENET_RX_D0", "ENET_RX_D1", "ENET_RX_D2", "ENET_RX_D3", /* 70 - 74 */ + "ENET_RX_CTRL", "ENET_MDC", "ENET_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 -89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&gpu { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + tca6416_u15: gpio@20 { /* u15 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "MIO26_PMU_INPUT_LS", "", /* 0 - 3 */ + "", "IIC_MUX_RESET_B", "GEM3_EXP_RESET_B", "MAX6643_FULL_SPEED", /* 4 - 7 */ + "FMCP_HSPC_PRSNT_M2C_B", "", "", "VCCINT_VRHOT_B", /* 10 - 13 */ + "", "8A34001_EXP_RST_B", "IRPS5401_ALERT_B", "INA226_PMBUS_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@75 { /* u17 */ + compatible = "nxp,pca9544"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* PS_PMBUS */ + /* PMBUS_ALERT done via pca9544 */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccint_io_bram_ps: ina226@41 { /* u57 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-io-bram-ps"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcc1v8: ina226@42 { /* u60 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v8"; + reg = <0x42>; + shunt-resistor = <2000>; + }; + vcc1v2: ina226@43 { /* u58 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vadj_fmc: ina226@45 { /* u62 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vadj-fmc"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + mgtavcc: ina226@46 { /* u67 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtavcc"; + reg = <0x46>; + shunt-resistor = <2000>; + }; + mgt1v2: ina226@47 { /* u63 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v2"; + reg = <0x47>; + shunt-resistor = <5000>; + }; + mgt1v8: ina226@48 { /* u64 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v8"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vccint_ams: ina226@49 { /* u61 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-ams"; + reg = <0x49>; + shunt-resistor = <5000>; + }; + dac_avtt: ina226@4a { /* u59 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avtt"; + reg = <0x4a>; + shunt-resistor = <5000>; + }; + dac_avccaux: ina226@4b { /* u124 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avccaux"; + reg = <0x4b>; + shunt-resistor = <5000>; + }; + adc_avcc: ina226@4c { /* u75 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avcc"; + reg = <0x4c>; + shunt-resistor = <5000>; + }; + adc_avccaux: ina226@4d { /* u71 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avccaux"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + dac_avcc: ina226@4e { /* u77 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avcc"; + reg = <0x4e>; + shunt-resistor = <5000>; + }; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* NC */ + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* u104 - ir35215 0x10/0x40 */ + /* u127 - ir38164 0x1b/0x4b */ + /* u112 - ir38164 0x13/0x43 */ + /* u123 - ir38164 0x1c/0x4c */ + + irps5401_44: irps5401@44 { /* IRPS5401 - u53 */ + compatible = "infineon,irps5401"; + reg = <0x44>; /* i2c addr 0x14 */ + }; + irps5401_45: irps5401@45 { /* IRPS5401 - u55 */ + compatible = "infineon,irps5401"; + reg = <0x45>; /* i2c addr 0x15 */ + }; + /* J21 header too */ + + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* SYSMON */ + }; + }; + /* u38 MPS430 */ +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + i2c-mux@74 { + compatible = "nxp,pca9548"; /* u20 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + i2c-mux-idle-disconnect; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c_eeprom: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* + * IIC_EEPROM 1kB memory which uses 256B blocks + * where every block has different address. + * 0 - 256B address 0x54 + * 256B - 512B address 0x55 + * 512B - 768B address 0x56 + * 768B - 1024B address 0x57 + */ + eeprom: eeprom@54 { /* u21 */ + compatible = "atmel,24c128"; + reg = <0x54>; + }; + }; + i2c_si5341: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + si5341: clock-generator@36 { /* SI5341 - u43 */ + compatible = "silabs,si5341"; + reg = <0x36>; + #clock-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&ref48>; + clock-names = "xtal"; + clock-output-names = "si5341"; + + si5341_2: out@2 { + /* refclk2 for PS-GT, used for USB3 */ + reg = <2>; + always-on; + }; + si5341_3: out@3 { + /* refclk3 for PS-GT, used for SATA */ + reg = <3>; + always-on; + }; + si5341_5: out@5 { + /* refclk5 PL CLK100 */ + reg = <5>; + always-on; + }; + si5341_6: out@6 { + /* refclk6 PL CLK125 */ + reg = <6>; + always-on; + }; + si5341_9: out@9 { + /* refclk9 used for PS_REF_CLK 33.3 MHz */ + reg = <9>; + always-on; + }; + }; + }; + i2c_si570_user_c0: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_1: clock-generator@5d { /* USER C0 SI570 - u47 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; + clock-frequency = <300000000>; + clock-output-names = "si570_user_c0"; + }; + }; + i2c_si570_mgt: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_2: clock-generator@5d { /* USER MGT SI570 - u48 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_mgt"; + }; + }; + i2c_8a34001: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + idt_8a34001: phc@5b { + compatible = "idt,8a34001"; /* u409B */ + reg = <0x5b>; + }; + }; + i2c_clk104: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* CLK104_SDA */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* RFMCP connector */ + }; + /* 7 NC */ + }; + + i2c-mux@75 { + compatible = "nxp,pca9548"; /* u22 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c-mux-idle-disconnect; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* FMCP_HSPC_IIC */ + }; + i2c_si570_user_c1: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + si570_3: clock-generator@5d { /* USER C1 SI570 - u130 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; + clock-frequency = <300000000>; + clock-output-names = "si570_user_c1"; + }; + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* SYSMON */ + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* DDR4 SODIMM */ + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* SFP3 */ + }; + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* SFP2 */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* SFP1 */ + }; + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* SFP0 */ + }; + }; + /* MSP430 */ +}; + +&pinctrl0 { + status = "okay"; + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_3_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_3_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_14_grp", "gpio0_15_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_14_grp", "gpio0_15_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_4_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_4_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + mux { + groups = "gpio0_16_grp", "gpio0_17_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_16_grp", "gpio0_17_grp"; + slew-rate = ; + power-source = ; + }; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* U11 and U12 MT25QU02GCBBE12 1Gb */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x10000000 0x10000000>; /* 256MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + }; +}; + +&rtc { + status = "okay"; +}; + +&sata { + status = "okay"; + /* SATA OOB timing settings */ + ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>; + ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>; + ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>; + ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>; + phy-names = "sata-phy"; + phys = <&psgtr 3 PHY_TYPE_SATA 1 3>; +}; + +/* SD1 with level shifter */ +&sdhci1 { + status = "okay"; + disable-wp; + /* + * This property should be removed for supporting UHS mode + */ + no-1-8-v; + xlnx,mio-bank = <1>; +}; + +&uart0 { + status = "okay"; +}; + +/* ULPI SMSC USB3320 */ +&usb0 { + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu670-revA.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu670-revA.dts @@ -0,0 +1,669 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP ZCU670 (67DR) + * + * (C) Copyright 2017 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "ZynqMP ZCU670 RevA"; + compatible = "xlnx,zynqmp-zcu670-revA", "xlnx,zynqmp-zcu670", + "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x0 0x80000000>; + /* Another 4GB connected to PL */ + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + switch-1 { + label = "sw1"; + gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { + label = "heartbeat"; /* DS1 */ + gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + ina226-vccint { + compatible = "iio-hwmon"; + io-channels = <&vccint 0>, <&vccint 1>, <&vccint 2>, <&vccint 3>; + }; + ina226-vccint-io-bram-ps { + compatible = "iio-hwmon"; + io-channels = <&vccint_io_bram_ps 0>, <&vccint_io_bram_ps 1>, <&vccint_io_bram_ps 2>, <&vccint_io_bram_ps 3>; + }; + ina226-vcc1v8 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v8 0>, <&vcc1v8 1>, <&vcc1v8 2>, <&vcc1v8 3>; + }; + ina226-vcc1v2 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2 0>, <&vcc1v2 1>, <&vcc1v2 2>, <&vcc1v2 3>; + }; + ina226-vadj-fmc { + compatible = "iio-hwmon"; + io-channels = <&vadj_fmc 0>, <&vadj_fmc 1>, <&vadj_fmc 2>, <&vadj_fmc 3>; + }; + ina226-mgtavcc { + compatible = "iio-hwmon"; + io-channels = <&mgtavcc 0>, <&mgtavcc 1>, <&mgtavcc 2>, <&mgtavcc 3>; + }; + ina226-mgt1v2 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v2 0>, <&mgt1v2 1>, <&mgt1v2 2>, <&mgt1v2 3>; + }; + ina226-mgt1v8 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v8 0>, <&mgt1v8 1>, <&mgt1v8 2>, <&mgt1v8 3>; + }; + ina226-vccint-ams { + compatible = "iio-hwmon"; + io-channels = <&vccint_ams 0>, <&vccint_ams 1>, <&vccint_ams 2>, <&vccint_ams 3>; + }; + ina226-dac-avtt { + compatible = "iio-hwmon"; + io-channels = <&dac_avtt 0>, <&dac_avtt 1>, <&dac_avtt 2>, <&dac_avtt 3>; + }; + ina226-dac-avccaux { + compatible = "iio-hwmon"; + io-channels = <&dac_avccaux 0>, <&dac_avccaux 1>, <&dac_avccaux 2>, <&dac_avccaux 3>; + }; + ina226-adc-avcc { + compatible = "iio-hwmon"; + io-channels = <&adc_avcc 0>, <&adc_avcc 1>, <&adc_avcc 2>, <&adc_avcc 3>; + }; + ina226-adc-avccaux { + compatible = "iio-hwmon"; + io-channels = <&adc_avccaux 0>, <&adc_avccaux 1>, <&adc_avccaux 2>, <&adc_avccaux 3>; + }; + ina226-dac-avcc { + compatible = "iio-hwmon"; + io-channels = <&dac_avcc 0>, <&dac_avcc 1>, <&dac_avcc 2>, <&dac_avcc 3>; + }; + + /* 48MHz reference crystal */ + ref48: ref48M { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + }; + + si5381_6: si5381-6 { /* refclk_usb3 - u43 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; +}; + +&dcc { + status = "okay"; +}; + +&fpd_dma_chan1 { + status = "okay"; +}; + +&fpd_dma_chan2 { + status = "okay"; +}; + +&fpd_dma_chan3 { + status = "okay"; +}; + +&fpd_dma_chan4 { + status = "okay"; +}; + +&fpd_dma_chan5 { + status = "okay"; +}; + +&fpd_dma_chan6 { + status = "okay"; +}; + +&fpd_dma_chan7 { + status = "okay"; +}; + +&fpd_dma_chan8 { + status = "okay"; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "QSPI_LWR_CLK", "QSPI_LWR_DQ1", "QSPI_LWR_DQ2", "QSPI_LWR_DQ3", "QSPI_LWR_DQ0", /* 0 - 4 */ + "QSPI_LWR_CS_B", "", "QSPI_UPR_CS_B", "QSPI_UPR_DQ0", "QSPI_UPR_DQ1", /* 5 - 9 */ + "QSPI_UPR_DQ2", "QSPI_UPR_DQ3", "QSPI_UPR_CLK", "PS_GPIO2", "I2C0_SCL", /* 10 - 14 */ + "I2C0_SDA", "I2C1_SCL", "I2C1_SDA", "UART0_TXD", "UART0_RXD", /* 15 - 19 */ + "", "", "BUTTON", "LED", "", /* 20 - 24 */ + "", "PMU_INPUT", "SFP3_TX_DISABLE", "SFP2_TX_DISABLE", "SFP1_TX_DISABLE", /* 25 - 29 */ + "SFP0_TX_DISABLE", "", "PMU_GPO0", "PMU_GPO1", "PMU_GPO2", /* 30 - 34 */ + "PMU_GPO3", "PMU_GPO4", "PMU_GPO5", "PS_GPIO1", "SDIO_SEL", /* 35 - 39 */ + "SDIO_DIR_CMD", "SDIO_DIR_DAT0", "SDIO_DIR_DAT1", "SD_PWR_RST", "", /* 40 - 44 */ + "SDIO_DETECT", "SDIO_DAT0", "SDIO_DAT1", "SDIO_DAT2", "SDIO_DAT3", /* 45 - 49 */ + "SDIO_CMD", "SDIO_CLK", "USB_CLK", "USB_DIR", "USB_DATA2", /* 50 - 54 */ + "USB_NXT", "USB_DATA0", "USB_DATA1", "USB_STP", "USB_DATA3", /* 55 - 59 */ + "USB_DATA4", "USB_DATA5", "USB_DATA6", "USB_DATA7", "ENET_TX_CLK", /* 60 - 64 */ + "ENET_TX_D0", "ENET_TX_D1", "ENET_TX_D2", "ENET_TX_D3", "ENET_TX_CTRL", /* 65 - 69 */ + "ENET_RX_CLK", "ENET_RX_D0", "ENET_RX_D1", "ENET_RX_D2", "ENET_RX_D3", /* 70 - 74 */ + "ENET_RX_CTRL", "ENET_MDC", "ENET_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 - 89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + tca6416_u15: gpio@20 { /* u15 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "MIO26_PMU_INPUT_LS", "DAC_AVTT_VOUT_SEL", /* 0 - 3 */ + "SI5381_INT_ALM", "IIC_MUX_RESET_B", "GEM3_EXP_RESET_B", "MAX6643_FULL_SPEED", /* 4 - 7 */ + "FMCP_HSPC_PRSNT_M2C_B", "", "", "VCCINT_VRHOT_B", /* 10 - 13 */ + "", "8A34001_EXP_RST_B", "IRPS5401_ALERT_B", "INA226_PMBUS_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@75 { /* u17 */ + compatible = "nxp,pca9544"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* PS_PMBUS */ + /* PMBUS_ALERT done via pca9544 */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccint_io_bram_ps: ina226@41 { /* u57 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-io-bram-ps"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcc1v8: ina226@42 { /* u60 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v8"; + reg = <0x42>; + shunt-resistor = <2000>; + }; + vcc1v2: ina226@43 { /* u58 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vadj_fmc: ina226@45 { /* u62 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vadj-fmc"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + mgtavcc: ina226@46 { /* u67 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtavcc"; + reg = <0x46>; + shunt-resistor = <2000>; + }; + mgt1v2: ina226@47 { /* u63 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v2"; + reg = <0x47>; + shunt-resistor = <5000>; /* Not in schematics */ + }; + mgt1v8: ina226@48 { /* u64 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v8"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vccint_ams: ina226@49 { /* u61 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-ams"; + reg = <0x49>; + shunt-resistor = <5000>; + }; + dac_avtt: ina226@4a { /* u59 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avtt"; + reg = <0x4a>; + shunt-resistor = <5000>; + }; + dac_avccaux: ina226@4b { /* u124 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avccaux"; + reg = <0x4b>; + shunt-resistor = <5000>; + }; + adc_avcc: ina226@4c { /* u75 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avcc"; + reg = <0x4c>; + shunt-resistor = <5000>; + }; + adc_avccaux: ina226@4d { /* u71 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avccaux"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + dac_avcc: ina226@4e { /* u77 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avcc"; + reg = <0x4e>; + shunt-resistor = <5000>; + }; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* NC */ + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* u104 - ir35215 0x10/0x40 */ + /* u127 - ir38164 0x1b/0x4b */ + /* u112 - ir38164 0x13/0x43 */ + /* u123 - ir38164 0x1c/0x4c */ + + irps5401_44: irps5401@44 { /* IRPS5401 - u53 */ + compatible = "infineon,irps5401"; + reg = <0x44>; /* i2c addr 0x14 */ + }; + irps5401_45: irps5401@45 { /* IRPS5401 - u55 */ + compatible = "infineon,irps5401"; + reg = <0x45>; /* i2c addr 0x15 */ + }; + /* J21 header too */ + + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* SYSMON */ + }; + }; + /* u38 MPS430 */ +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + i2c-mux@74 { + compatible = "nxp,pca9548"; /* u20 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c_eeprom: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* + * IIC_EEPROM 1kB memory which uses 256B blocks + * where every block has different address. + * 0 - 256B address 0x54 + * 256B - 512B address 0x55 + * 512B - 768B address 0x56 + * 768B - 1024B address 0x57 + */ + eeprom: eeprom@54 { /* u21 */ + compatible = "atmel,24c128"; + reg = <0x54>; + }; + }; + i2c_si5381: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* SI5381 - u43 */ + /* si5381: clock-generator@68 { + reg = <0x68>; + };*/ + }; + i2c_si570_user_c0: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_1: clock-generator@5d { /* USER C0 SI570 - u47 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; + clock-frequency = <300000000>; + clock-output-names = "si570_user_c0"; + }; + }; + i2c_si570_mgt: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_2: clock-generator@5d { /* USER MGT SI570 - u48 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_mgt"; + }; + }; + i2c_8a34001: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* U409B - 8a34001 */ + }; + i2c_clk104: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* CLK104_SDA */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* RFMCP connector */ + }; + /* 7 NC */ + }; + + i2c-mux@75 { + compatible = "nxp,pca9548"; /* u22 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* FMCP_HSPC_IIC */ + }; + i2c_si570_psrefclk: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + si570_3: clock-generator@5d { /* USER SI570 PSREFCLK - u130 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "si570_ps_ref_clk"; + silabs,skip-recall; + }; + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* SYSMON */ + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* DDR4 SODIMM */ + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* SFP3 */ + }; + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* SFP2 */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* SFP1 */ + }; + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* SFP0 */ + }; + }; + /* u38 MPS430 */ +}; + +&pinctrl0 { + status = "okay"; + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_3_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_3_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_14_grp", "gpio0_15_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_14_grp", "gpio0_15_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_4_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_4_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + mux { + groups = "gpio0_16_grp", "gpio0_17_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_16_grp", "gpio0_17_grp"; + slew-rate = ; + power-source = ; + }; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* U11 and U12 MT25QU02GCBBE12 2Gb */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x10000000 0x10000000>; /* 256MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + }; +}; + +&rtc { + status = "okay"; +}; + +/* SD1 with level shifter */ +&sdhci1 { + status = "okay"; + disable-wp; + /* + * This property should be removed for supporting UHS mode + */ + no-1-8-v; + xlnx,mio-bank = <1>; +}; + +&psgtr { + status = "okay"; + /* hspc_dp4, hspc_dp5, usb3, hspc_dp6 */ + clocks = <&si5381_6>; + clock-names = "ref2"; +}; + +&uart0 { + status = "okay"; +}; + +/* ULPI SMSC USB3320 */ +&usb0 { + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zcu670-revB.dts +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp-zcu670-revB.dts @@ -0,0 +1,672 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx ZynqMP ZCU670 (67DR) revB + * + * (C) Copyright 2017 - 2022, Xilinx, Inc. + * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" +#include +#include +#include +#include + +/ { + model = "ZynqMP ZCU670 RevB"; + compatible = "xlnx,zynqmp-zcu670-revB", "xlnx,zynqmp-zcu670", + "xlnx,zynqmp"; + + aliases { + ethernet0 = &gem3; + i2c0 = &i2c0; + i2c1 = &i2c1; + mmc0 = &sdhci1; + nvmem0 = &eeprom; + rtc0 = &rtc; + serial0 = &uart0; + serial1 = &dcc; + spi0 = &qspi; + usb0 = &usb0; + }; + + chosen { + bootargs = "earlycon"; + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0 0 0 0x80000000>, <0x8 0x0 0x0 0x80000000>; + /* Another 4GB connected to PL */ + }; + + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + switch-1 { + label = "sw1"; + gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; + linux,code = ; + wakeup-source; + autorepeat; + }; + }; + + leds { + compatible = "gpio-leds"; + heartbeat-led { + label = "heartbeat"; /* DS1 */ + gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + ina226-vccint { + compatible = "iio-hwmon"; + io-channels = <&vccint 0>, <&vccint 1>, <&vccint 2>, <&vccint 3>; + }; + ina226-vccint-io-bram-ps { + compatible = "iio-hwmon"; + io-channels = <&vccint_io_bram_ps 0>, <&vccint_io_bram_ps 1>, <&vccint_io_bram_ps 2>, <&vccint_io_bram_ps 3>; + }; + ina226-vcc1v8 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v8 0>, <&vcc1v8 1>, <&vcc1v8 2>, <&vcc1v8 3>; + }; + ina226-vcc1v2 { + compatible = "iio-hwmon"; + io-channels = <&vcc1v2 0>, <&vcc1v2 1>, <&vcc1v2 2>, <&vcc1v2 3>; + }; + ina226-vadj-fmc { + compatible = "iio-hwmon"; + io-channels = <&vadj_fmc 0>, <&vadj_fmc 1>, <&vadj_fmc 2>, <&vadj_fmc 3>; + }; + ina226-mgtavcc { + compatible = "iio-hwmon"; + io-channels = <&mgtavcc 0>, <&mgtavcc 1>, <&mgtavcc 2>, <&mgtavcc 3>; + }; + ina226-mgt1v2 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v2 0>, <&mgt1v2 1>, <&mgt1v2 2>, <&mgt1v2 3>; + }; + ina226-mgt1v8 { + compatible = "iio-hwmon"; + io-channels = <&mgt1v8 0>, <&mgt1v8 1>, <&mgt1v8 2>, <&mgt1v8 3>; + }; + ina226-vccint-ams { + compatible = "iio-hwmon"; + io-channels = <&vccint_ams 0>, <&vccint_ams 1>, <&vccint_ams 2>, <&vccint_ams 3>; + }; + ina226-dac-avtt { + compatible = "iio-hwmon"; + io-channels = <&dac_avtt 0>, <&dac_avtt 1>, <&dac_avtt 2>, <&dac_avtt 3>; + }; + ina226-dac-avccaux { + compatible = "iio-hwmon"; + io-channels = <&dac_avccaux 0>, <&dac_avccaux 1>, <&dac_avccaux 2>, <&dac_avccaux 3>; + }; + ina226-adc-avcc { + compatible = "iio-hwmon"; + io-channels = <&adc_avcc 0>, <&adc_avcc 1>, <&adc_avcc 2>, <&adc_avcc 3>; + }; + ina226-adc-avccaux { + compatible = "iio-hwmon"; + io-channels = <&adc_avccaux 0>, <&adc_avccaux 1>, <&adc_avccaux 2>, <&adc_avccaux 3>; + }; + ina226-dac-avcc { + compatible = "iio-hwmon"; + io-channels = <&dac_avcc 0>, <&dac_avcc 1>, <&dac_avcc 2>, <&dac_avcc 3>; + }; + + /* 48MHz reference crystal */ + ref48: ref48M { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <48000000>; + }; + + si5381_6: si5381-6 { /* refclk_usb3 - u43 */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + }; +}; + +&dcc { + status = "okay"; +}; + +&fpd_dma_chan1 { + status = "okay"; +}; + +&fpd_dma_chan2 { + status = "okay"; +}; + +&fpd_dma_chan3 { + status = "okay"; +}; + +&fpd_dma_chan4 { + status = "okay"; +}; + +&fpd_dma_chan5 { + status = "okay"; +}; + +&fpd_dma_chan6 { + status = "okay"; +}; + +&fpd_dma_chan7 { + status = "okay"; +}; + +&fpd_dma_chan8 { + status = "okay"; +}; + +&gem3 { + status = "okay"; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&gpio { + status = "okay"; + gpio-line-names = "QSPI_LWR_CLK", "QSPI_LWR_DQ1", "QSPI_LWR_DQ2", "QSPI_LWR_DQ3", "QSPI_LWR_DQ0", /* 0 - 4 */ + "QSPI_LWR_CS_B", "", "QSPI_UPR_CS_B", "QSPI_UPR_DQ0", "QSPI_UPR_DQ1", /* 5 - 9 */ + "QSPI_UPR_DQ2", "QSPI_UPR_DQ3", "QSPI_UPR_CLK", "PS_GPIO2", "I2C0_SCL", /* 10 - 14 */ + "I2C0_SDA", "I2C1_SCL", "I2C1_SDA", "UART0_TXD", "UART0_RXD", /* 15 - 19 */ + "", "", "BUTTON", "LED", "", /* 20 - 24 */ + "", "PMU_INPUT", "SFP3_TX_DISABLE", "SFP2_TX_DISABLE", "SFP1_TX_DISABLE", /* 25 - 29 */ + "SFP0_TX_DISABLE", "", "PMU_GPO0", "PMU_GPO1", "PMU_GPO2", /* 30 - 34 */ + "PMU_GPO3", "PMU_GPO4", "PMU_GPO5", "PS_GPIO1", "SDIO_SEL", /* 35 - 39 */ + "SDIO_DIR_CMD", "SDIO_DIR_DAT0", "SDIO_DIR_DAT1", "SD_PWR_RST", "", /* 40 - 44 */ + "SDIO_DETECT", "SDIO_DAT0", "SDIO_DAT1", "SDIO_DAT2", "SDIO_DAT3", /* 45 - 49 */ + "SDIO_CMD", "SDIO_CLK", "USB_CLK", "USB_DIR", "USB_DATA2", /* 50 - 54 */ + "USB_NXT", "USB_DATA0", "USB_DATA1", "USB_STP", "USB_DATA3", /* 55 - 59 */ + "USB_DATA4", "USB_DATA5", "USB_DATA6", "USB_DATA7", "ENET_TX_CLK", /* 60 - 64 */ + "ENET_TX_D0", "ENET_TX_D1", "ENET_TX_D2", "ENET_TX_D3", "ENET_TX_CTRL", /* 65 - 69 */ + "ENET_RX_CLK", "ENET_RX_D0", "ENET_RX_D1", "ENET_RX_D2", "ENET_RX_D3", /* 70 - 74 */ + "ENET_RX_CTRL", "ENET_MDC", "ENET_MDIO", /* 75 - 77, MIO end and EMIO start */ + "", "", /* 78 - 79 */ + "", "", "", "", "", /* 80 - 84 */ + "", "", "", "", "", /* 85 - 89 */ + "", "", "", "", "", /* 90 - 94 */ + "", "", "", "", "", /* 95 - 99 */ + "", "", "", "", "", /* 100 - 104 */ + "", "", "", "", "", /* 105 - 109 */ + "", "", "", "", "", /* 110 - 114 */ + "", "", "", "", "", /* 115 - 119 */ + "", "", "", "", "", /* 120 - 124 */ + "", "", "", "", "", /* 125 - 129 */ + "", "", "", "", "", /* 130 - 134 */ + "", "", "", "", "", /* 135 - 139 */ + "", "", "", "", "", /* 140 - 144 */ + "", "", "", "", "", /* 145 - 149 */ + "", "", "", "", "", /* 150 - 154 */ + "", "", "", "", "", /* 155 - 159 */ + "", "", "", "", "", /* 160 - 164 */ + "", "", "", "", "", /* 165 - 169 */ + "", "", "", ""; /* 170 - 173 */ +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c0_default>; + pinctrl-1 = <&pinctrl_i2c0_gpio>; + scl-gpios = <&gpio 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + tca6416_u15: gpio@20 { /* u15 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "MIO26_PMU_INPUT_LS", "DAC_AVTT_VOUT_SEL", /* 0 - 3 */ + "SI5381_INT_ALM", "IIC_MUX_RESET_B", "GEM3_EXP_RESET_B", "MAX6643_FULL_SPEED", /* 4 - 7 */ + "FMCP_HSPC_PRSNT_M2C_B", "", "", "VCCINT_VRHOT_B", /* 10 - 13 */ + "", "8A34001_EXP_RST_B", "IRPS5401_ALERT_B", "INA226_PMBUS_ALERT"; /* 14 - 17 */ + }; + + i2c-mux@75 { /* u17 */ + compatible = "nxp,pca9544"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* PS_PMBUS */ + /* PMBUS_ALERT done via pca9544 */ + vccint: ina226@40 { /* u65 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint"; + reg = <0x40>; + shunt-resistor = <5000>; + }; + vccint_io_bram_ps: ina226@41 { /* u57 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-io-bram-ps"; + reg = <0x41>; + shunt-resistor = <5000>; + }; + vcc1v8: ina226@42 { /* u60 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v8"; + reg = <0x42>; + shunt-resistor = <2000>; + }; + vcc1v2: ina226@43 { /* u58 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vcc1v2"; + reg = <0x43>; + shunt-resistor = <5000>; + }; + vadj_fmc: ina226@45 { /* u62 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vadj-fmc"; + reg = <0x45>; + shunt-resistor = <5000>; + }; + mgtavcc: ina226@46 { /* u67 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgtavcc"; + reg = <0x46>; + shunt-resistor = <2000>; + }; + mgt1v2: ina226@47 { /* u63 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v2"; + reg = <0x47>; + shunt-resistor = <5000>; /* Not in schematics */ + }; + mgt1v8: ina226@48 { /* u64 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-mgt1v8"; + reg = <0x48>; + shunt-resistor = <5000>; + }; + vccint_ams: ina226@49 { /* u61 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-vccint-ams"; + reg = <0x49>; + shunt-resistor = <5000>; + }; + dac_avtt: ina226@4a { /* u59 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avtt"; + reg = <0x4a>; + shunt-resistor = <5000>; + }; + dac_avccaux: ina226@4b { /* u124 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avccaux"; + reg = <0x4b>; + shunt-resistor = <5000>; + }; + adc_avcc: ina226@4c { /* u75 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avcc"; + reg = <0x4c>; + shunt-resistor = <5000>; + }; + adc_avccaux: ina226@4d { /* u71 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-adc-avccaux"; + reg = <0x4d>; + shunt-resistor = <5000>; + }; + dac_avcc: ina226@4e { /* u77 */ + compatible = "ti,ina226"; + #io-channel-cells = <1>; + label = "ina226-dac-avcc"; + reg = <0x4e>; + shunt-resistor = <5000>; + }; + }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* NC */ + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* u104 - ir35215 0x10/0x40 */ + /* u127 - ir38164 0x1b/0x4b */ + /* u112 - ir38164 0x13/0x43 */ + /* u123 - ir38164 0x1c/0x4c */ + + irps5401_44: irps5401@44 { /* IRPS5401 - u53 */ + compatible = "infineon,irps5401"; + reg = <0x44>; /* i2c addr 0x14 */ + }; + irps5401_45: irps5401@45 { /* IRPS5401 - u55 */ + compatible = "infineon,irps5401"; + reg = <0x45>; /* i2c addr 0x15 */ + }; + /* J21 header too */ + + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* SYSMON */ + }; + }; + /* u38 MPS430 */ +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + i2c-mux@74 { + compatible = "nxp,pca9548"; /* u20 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c_eeprom: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* + * IIC_EEPROM 1kB memory which uses 256B blocks + * where every block has different address. + * 0 - 256B address 0x54 + * 256B - 512B address 0x55 + * 512B - 768B address 0x56 + * 768B - 1024B address 0x57 + */ + eeprom: eeprom@54 { /* u21 */ + compatible = "atmel,24c128"; + reg = <0x54>; + }; + }; + i2c_si5381: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + /* SI5381 - u43 */ + /* si5381: clock-generator@68 { + reg = <0x68>; + };*/ + }; + i2c_si570_user_c0: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + si570_1: clock-generator@5d { /* USER C0 SI570 - u47 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <300000000>; + clock-frequency = <300000000>; + clock-output-names = "si570_user_c0"; + }; + }; + i2c_si570_mgt: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + si570_2: clock-generator@5d { /* USER MGT SI570 - u48 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <156250000>; + clock-frequency = <156250000>; + clock-output-names = "si570_mgt"; + }; + }; + i2c_8a34001: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* U409B - 8a34001 */ + }; + i2c_clk104: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* CLK104_SDA */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* RFMCP connector */ + }; + /* 7 NC */ + }; + + i2c-mux@75 { + compatible = "nxp,pca9548"; /* u22 */ + #address-cells = <1>; + #size-cells = <0>; + reg = <0x75>; + /* FIXME reset-gpios = <&tca6416_u15 SYSCTLR_IIC_MUX0_RESET_B GPIO_ACTIVE_HIGH>; */ + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + /* FMCP_HSPC_IIC */ + }; + i2c_si570_psrefclk: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + si570_3: clock-generator@5d { /* USER SI570 PSREFCLK - u130 */ + #clock-cells = <0>; + compatible = "silabs,si570"; + reg = <0x5d>; + temperature-stability = <50>; + factory-fout = <33333333>; + clock-frequency = <33333333>; + clock-output-names = "si570_ps_ref_clk"; + silabs,skip-recall; + }; + }; + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + /* SYSMON */ + }; + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + /* DDR4 SODIMM */ + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + /* SFP3 */ + }; + i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <5>; + /* SFP2 */ + }; + i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <6>; + /* SFP1 */ + }; + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + /* SFP0 */ + }; + }; + /* u38 MPS430 */ +}; + +&pinctrl0 { + status = "okay"; + pinctrl_i2c0_default: i2c0-default { + mux { + groups = "i2c0_3_grp"; + function = "i2c0"; + }; + + conf { + groups = "i2c0_3_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c0_gpio: i2c0-gpio-grp { + mux { + groups = "gpio0_14_grp", "gpio0_15_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_14_grp", "gpio0_15_grp"; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_default: i2c1-default { + mux { + groups = "i2c1_4_grp"; + function = "i2c1"; + }; + + conf { + groups = "i2c1_4_grp"; + bias-pull-up; + slew-rate = ; + power-source = ; + }; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + mux { + groups = "gpio0_16_grp", "gpio0_17_grp"; + function = "gpio0"; + }; + + conf { + groups = "gpio0_16_grp", "gpio0_17_grp"; + slew-rate = ; + power-source = ; + }; + }; +}; + +&qspi { + status = "okay"; + num-cs = <2>; + flash@0 { + compatible = "m25p80", "jedec,spi-nor"; /* U11 and U12 MT25QU02GCBBE12 2Gb */ + #address-cells = <1>; + #size-cells = <1>; + reg = <0>, <1>; + parallel-memories = /bits/ 64 <0x10000000 0x10000000>; /* 256MB */ + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; /* FIXME also DUAL configuration possible */ + spi-max-frequency = <108000000>; /* Based on DC1 spec */ + }; +}; + +&rtc { + status = "okay"; +}; + +/* SD1 with level shifter */ +&sdhci1 { + status = "okay"; + disable-wp; + /* + * This property should be removed for supporting UHS mode + */ + no-1-8-v; + xlnx,mio-bank = <1>; + clk-phase-sd-hs = <120>, <60>; + clk-phase-uhs-sdr25 = <132>, <60>; + clk-phase-uhs-ddr50 = <153>, <48>; +}; + +&psgtr { + status = "okay"; + /* hspc_dp4, hspc_dp5, usb3, hspc_dp6 */ + clocks = <&si5381_6>; + clock-names = "ref2"; +}; + +&uart0 { + status = "okay"; +}; + +/* ULPI SMSC USB3320 */ +&usb0 { + status = "okay"; + phy-names = "usb3-phy"; + phys = <&psgtr 2 PHY_TYPE_USB3 0 2>; +}; + +&dwc3_0 { + status = "okay"; + dr_mode = "host"; + snps,usb3_lpm_capable; +}; --- linux-xilinx-6.8.0.orig/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ linux-xilinx-6.8.0/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -24,6 +24,13 @@ #address-cells = <2>; #size-cells = <2>; + options { + u-boot { + compatible = "u-boot,config"; + bootscr-address = /bits/ 64 <0x20000000>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -113,22 +120,6 @@ }; }; - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - rproc_0_fw_image: memory@3ed00000 { - no-map; - reg = <0x0 0x3ed00000 0x0 0x40000>; - }; - - rproc_1_fw_image: memory@3ef00000 { - no-map; - reg = <0x0 0x3ef00000 0x0 0x40000>; - }; - }; - zynqmp_ipi: zynqmp-ipi { bootph-all; compatible = "xlnx,zynqmp-ipi-mailbox"; @@ -180,13 +171,18 @@ }; firmware { + optee: optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + zynqmp_firmware: zynqmp-firmware { compatible = "xlnx,zynqmp-firmware"; #power-domain-cells = <1>; method = "smc"; bootph-all; - zynqmp_power: zynqmp-power { + zynqmp_power: power-management { bootph-all; compatible = "xlnx,zynqmp-power"; interrupt-parent = <&gic>; @@ -195,13 +191,71 @@ mbox-names = "tx", "rx"; }; - nvmem-firmware { + soc-nvmem { compatible = "xlnx,zynqmp-nvmem-fw"; - #address-cells = <1>; - #size-cells = <1>; - - soc_revision: soc-revision@0 { - reg = <0x0 0x4>; + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + soc_revision: soc-revision@0 { + reg = <0x0 0x4>; + }; + /* efuse access */ + efuse_dna: efuse-dna@c { + reg = <0xc 0xc>; + }; + efuse_usr0: efuse-usr0@20 { + reg = <0x20 0x4>; + }; + efuse_usr1: efuse-usr1@24 { + reg = <0x24 0x4>; + }; + efuse_usr2: efuse-usr2@28 { + reg = <0x28 0x4>; + }; + efuse_usr3: efuse-usr3@2c { + reg = <0x2c 0x4>; + }; + efuse_usr4: efuse-usr4@30 { + reg = <0x30 0x4>; + }; + efuse_usr5: efuse-usr5@34 { + reg = <0x34 0x4>; + }; + efuse_usr6: efuse-usr6@38 { + reg = <0x38 0x4>; + }; + efuse_usr7: efuse-usr7@3c { + reg = <0x3c 0x4>; + }; + efuse_miscusr: efuse-miscusr@40 { + reg = <0x40 0x4>; + }; + efuse_chash: efuse-chash@50 { + reg = <0x50 0x4>; + }; + efuse_pufmisc: efuse-pufmisc@54 { + reg = <0x54 0x4>; + }; + efuse_sec: efuse-sec@58 { + reg = <0x58 0x4>; + }; + efuse_spkid: efuse-spkid@5c { + reg = <0x5c 0x4>; + }; + efuse_aeskey: efuse-aeskey@60 { + reg = <0x60 0x20>; + }; + efuse_ppk0hash: efuse-ppk0hash@a0 { + reg = <0xa0 0x30>; + }; + efuse_ppk1hash: efuse-ppk1hash@d0 { + reg = <0xd0 0x30>; + }; + efuse_pufuser: efuse-pufuser@100 { + reg = <0x100 0x7F>; + }; }; }; @@ -209,10 +263,6 @@ compatible = "xlnx,zynqmp-pcap-fpga"; }; - xlnx_aes: zynqmp-aes { - compatible = "xlnx,zynqmp-aes"; - }; - zynqmp_reset: reset-controller { compatible = "xlnx,zynqmp-reset"; #reset-cells = <1>; @@ -240,7 +290,7 @@ ; }; - fpga_full: fpga-full { + fpga_full: fpga-region { compatible = "fpga-region"; fpga-mgr = <&zynqmp_pcap>; #address-cells = <2>; @@ -248,23 +298,6 @@ ranges; }; - remoteproc { - compatible = "xlnx,zynqmp-r5fss"; - xlnx,cluster-mode = <1>; - - r5f-0 { - compatible = "xlnx,zynqmp-r5f"; - power-domains = <&zynqmp_firmware PD_RPU_0>; - memory-region = <&rproc_0_fw_image>; - }; - - r5f-1 { - compatible = "xlnx,zynqmp-r5f"; - power-domains = <&zynqmp_firmware PD_RPU_1>; - memory-region = <&rproc_1_fw_image>; - }; - }; - amba: axi { compatible = "simple-bus"; bootph-all; @@ -281,6 +314,7 @@ interrupt-parent = <&gic>; tx-fifo-depth = <0x40>; rx-fifo-depth = <0x40>; + resets = <&zynqmp_reset ZYNQMP_RESET_CAN0>; power-domains = <&zynqmp_firmware PD_CAN_0>; }; @@ -293,6 +327,7 @@ interrupt-parent = <&gic>; tx-fifo-depth = <0x40>; rx-fifo-depth = <0x40>; + resets = <&zynqmp_reset ZYNQMP_RESET_CAN1>; power-domains = <&zynqmp_firmware PD_CAN_1>; }; @@ -326,7 +361,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14e8>; + /* iommus = <&smmu 0x14e8>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -339,7 +374,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14e9>; + /* iommus = <&smmu 0x14e9>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -352,7 +387,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14ea>; + /* iommus = <&smmu 0x14ea>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -365,7 +400,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14eb>; + /* iommus = <&smmu 0x14eb>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -378,7 +413,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14ec>; + /* iommus = <&smmu 0x14ec>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -391,7 +426,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14ed>; + /* iommus = <&smmu 0x14ed>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -404,7 +439,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14ee>; + /* iommus = <&smmu 0x14ee>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -417,7 +452,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <128>; - iommus = <&smmu 0x14ef>; + /* iommus = <&smmu 0x14ef>; */ power-domains = <&zynqmp_firmware PD_GDMA>; }; @@ -462,7 +497,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x868>; + /* iommus = <&smmu 0x868>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -475,7 +510,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x869>; + /* iommus = <&smmu 0x869>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -488,7 +523,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x86a>; + /* iommus = <&smmu 0x86a>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -501,7 +536,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x86b>; + /* iommus = <&smmu 0x86b>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -514,7 +549,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x86c>; + /* iommus = <&smmu 0x86c>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -527,7 +562,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x86d>; + /* iommus = <&smmu 0x86d>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -540,7 +575,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x86e>; + /* iommus = <&smmu 0x86e>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -553,7 +588,7 @@ clock-names = "clk_main", "clk_apb"; #dma-cells = <1>; xlnx,bus-width = <64>; - iommus = <&smmu 0x86f>; + /* iommus = <&smmu 0x86f>; */ power-domains = <&zynqmp_firmware PD_ADMA>; }; @@ -573,7 +608,7 @@ interrupts = ; #address-cells = <1>; #size-cells = <0>; - iommus = <&smmu 0x872>; + /* iommus = <&smmu 0x872>; */ power-domains = <&zynqmp_firmware PD_NAND>; }; @@ -585,7 +620,7 @@ ; reg = <0x0 0xff0b0000 0x0 0x1000>; clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; - iommus = <&smmu 0x874>; + /* iommus = <&smmu 0x874>; */ power-domains = <&zynqmp_firmware PD_ETH_0>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM0>; reset-names = "gem0_rst"; @@ -599,7 +634,7 @@ ; reg = <0x0 0xff0c0000 0x0 0x1000>; clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; - iommus = <&smmu 0x875>; + /* iommus = <&smmu 0x875>; */ power-domains = <&zynqmp_firmware PD_ETH_1>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM1>; reset-names = "gem1_rst"; @@ -613,7 +648,7 @@ ; reg = <0x0 0xff0d0000 0x0 0x1000>; clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; - iommus = <&smmu 0x876>; + /* iommus = <&smmu 0x876>; */ power-domains = <&zynqmp_firmware PD_ETH_2>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM2>; reset-names = "gem2_rst"; @@ -627,7 +662,7 @@ ; reg = <0x0 0xff0e0000 0x0 0x1000>; clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk"; - iommus = <&smmu 0x877>; + /* iommus = <&smmu 0x877>; */ power-domains = <&zynqmp_firmware PD_ETH_3>; resets = <&zynqmp_reset ZYNQMP_RESET_GEM3>; reset-names = "gem3_rst"; @@ -670,6 +705,85 @@ power-domains = <&zynqmp_firmware PD_I2C_1>; }; + ocm: memory-controller@ff960000 { + compatible = "xlnx,zynqmp-ocmc-1.0"; + reg = <0x0 0xff960000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + }; + + perf_monitor_ocm: perf-monitor@ffa00000 { + compatible = "xlnx,axi-perf-monitor"; + reg = <0x0 0xffa00000 0x0 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + xlnx,enable-profile = <0>; + xlnx,enable-trace = <0>; + xlnx,num-monitor-slots = <1>; + xlnx,enable-event-count = <1>; + xlnx,enable-event-log = <1>; + xlnx,have-sampled-metric-cnt = <1>; + xlnx,num-of-counters = <8>; + xlnx,metric-count-width = <32>; + xlnx,metrics-sample-count-width = <32>; + xlnx,global-count-width = <32>; + xlnx,metric-count-scale = <1>; + }; + + perf_monitor_ddr: perf-monitor@fd0b0000 { + compatible = "xlnx,axi-perf-monitor"; + reg = <0x0 0xfd0b0000 0x0 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + xlnx,enable-profile = <0>; + xlnx,enable-trace = <0>; + xlnx,num-monitor-slots = <6>; + xlnx,enable-event-count = <1>; + xlnx,enable-event-log = <0>; + xlnx,have-sampled-metric-cnt = <1>; + xlnx,num-of-counters = <10>; + xlnx,metric-count-width = <32>; + xlnx,metrics-sample-count-width = <32>; + xlnx,global-count-width = <32>; + xlnx,metric-count-scale = <1>; + }; + + perf_monitor_cci: perf-monitor@fd490000 { + compatible = "xlnx,axi-perf-monitor"; + reg = <0x0 0xfd490000 0x0 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + xlnx,enable-profile = <0>; + xlnx,enable-trace = <0>; + xlnx,num-monitor-slots = <1>; + xlnx,enable-event-count = <1>; + xlnx,enable-event-log = <0>; + xlnx,have-sampled-metric-cnt = <1>; + xlnx,num-of-counters = <8>; + xlnx,metric-count-width = <32>; + xlnx,metrics-sample-count-width = <32>; + xlnx,global-count-width = <32>; + xlnx,metric-count-scale = <1>; + }; + + perf_monitor_lpd: perf-monitor@ffa10000 { + compatible = "xlnx,axi-perf-monitor"; + reg = <0x0 0xffa10000 0x0 0x10000>; + interrupts = ; + interrupt-parent = <&gic>; + xlnx,enable-profile = <0>; + xlnx,enable-trace = <0>; + xlnx,num-monitor-slots = <1>; + xlnx,enable-event-count = <1>; + xlnx,enable-event-log = <1>; + xlnx,have-sampled-metric-cnt = <1>; + xlnx,num-of-counters = <8>; + xlnx,metric-count-width = <32>; + xlnx,metrics-sample-count-width = <32>; + xlnx,global-count-width = <32>; + xlnx,metric-count-scale = <1>; + }; + pcie: pcie@fd0e0000 { compatible = "xlnx,nwl-pcie-2.11"; status = "disabled"; @@ -689,7 +803,7 @@ msi-parent = <&pcie>; reg = <0x0 0xfd0e0000 0x0 0x1000>, <0x0 0xfd480000 0x0 0x1000>, - <0x80 0x00000000 0x0 0x1000000>; + <0x80 0x00000000 0x0 0x10000000>; reg-names = "breg", "pcireg", "cfg"; ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000>,/* non-prefetchable memory */ <0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */ @@ -699,7 +813,7 @@ <0x0 0x0 0x0 0x2 &pcie_intc 0x2>, <0x0 0x0 0x0 0x3 &pcie_intc 0x3>, <0x0 0x0 0x0 0x4 &pcie_intc 0x4>; - iommus = <&smmu 0x4d0>; + /* iommus = <&smmu 0x4d0>; */ power-domains = <&zynqmp_firmware PD_PCIE>; pcie_intc: legacy-interrupt-controller { interrupt-controller; @@ -720,7 +834,7 @@ <0x0 0xc0000000 0x0 0x8000000>; #address-cells = <1>; #size-cells = <0>; - iommus = <&smmu 0x873>; + /* iommus = <&smmu 0x873>; */ power-domains = <&zynqmp_firmware PD_QSPI>; }; @@ -752,8 +866,8 @@ interrupts = ; power-domains = <&zynqmp_firmware PD_SATA>; resets = <&zynqmp_reset ZYNQMP_RESET_SATA>; - iommus = <&smmu 0x4c0>, <&smmu 0x4c1>, - <&smmu 0x4c2>, <&smmu 0x4c3>; + /* iommus = <&smmu 0x4c0>, <&smmu 0x4c1>, <&smmu 0x4c2>, <&smmu 0x4c3>; */ + /* dma-coherent; */ }; sdhci0: mmc@ff160000 { @@ -764,7 +878,7 @@ interrupts = ; reg = <0x0 0xff160000 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; - iommus = <&smmu 0x870>; + /* iommus = <&smmu 0x870>; */ #clock-cells = <1>; clock-output-names = "clk_out_sd0", "clk_in_sd0"; power-domains = <&zynqmp_firmware PD_SD_0>; @@ -779,7 +893,7 @@ interrupts = ; reg = <0x0 0xff170000 0x0 0x1000>; clock-names = "clk_xin", "clk_ahb"; - iommus = <&smmu 0x871>; + /* iommus = <&smmu 0x871>; */ #clock-cells = <1>; clock-output-names = "clk_out_sd1", "clk_in_sd1"; power-domains = <&zynqmp_firmware PD_SD_1>; @@ -893,6 +1007,7 @@ reg = <0x0 0xff000000 0x0 0x1000>; clock-names = "uart_clk", "pclk"; power-domains = <&zynqmp_firmware PD_UART_0>; + resets = <&zynqmp_reset ZYNQMP_RESET_UART0>; }; uart1: serial@ff010000 { @@ -904,6 +1019,7 @@ reg = <0x0 0xff010000 0x0 0x1000>; clock-names = "uart_clk", "pclk"; power-domains = <&zynqmp_firmware PD_UART_1>; + resets = <&zynqmp_reset ZYNQMP_RESET_UART1>; }; usb0: usb@ff9d0000 { @@ -912,6 +1028,7 @@ status = "disabled"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x0 0xff9d0000 0x0 0x100>; + clock-names = "bus_clk", "ref_clk"; power-domains = <&zynqmp_firmware PD_USB_0>; resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>, <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>, @@ -922,15 +1039,17 @@ dwc3_0: usb@fe200000 { compatible = "snps,dwc3"; + status = "disabled"; reg = <0x0 0xfe200000 0x0 0x40000>; interrupt-parent = <&gic>; - interrupt-names = "host", "peripheral", "otg"; + interrupt-names = "host", "peripheral", "otg", "wakeup"; interrupts = , , - ; - clock-names = "bus_early", "ref"; - iommus = <&smmu 0x860>; + , + ; + /* iommus = <&smmu 0x860>; */ snps,quirk-frame-length-adjustment = <0x20>; + clock-names = "ref"; snps,resume-hs-terminations; /* dma-coherent; */ }; @@ -942,6 +1061,7 @@ status = "disabled"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x0 0xff9e0000 0x0 0x100>; + clock-names = "bus_clk", "ref_clk"; power-domains = <&zynqmp_firmware PD_USB_1>; resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>, <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>, @@ -951,15 +1071,17 @@ dwc3_1: usb@fe300000 { compatible = "snps,dwc3"; + status = "disabled"; reg = <0x0 0xfe300000 0x0 0x40000>; interrupt-parent = <&gic>; - interrupt-names = "host", "peripheral", "otg"; + interrupt-names = "host", "peripheral", "otg", "wakeup"; interrupts = , , - ; - clock-names = "bus_early", "ref"; - iommus = <&smmu 0x861>; + , + ; + /* iommus = <&smmu 0x861>; */ snps,quirk-frame-length-adjustment = <0x20>; + clock-names = "ref"; snps,resume-hs-terminations; /* dma-coherent; */ }; @@ -1005,8 +1127,6 @@ compatible = "xlnx,zynqmp-ams-pl"; status = "disabled"; reg = <0x400 0x400>; - #address-cells = <1>; - #size-cells = <0>; }; }; @@ -1018,20 +1138,28 @@ interrupt-parent = <&gic>; clock-names = "axi_clk"; power-domains = <&zynqmp_firmware PD_DP>; + dma-channels = <6>; + /* iommus = <&smmu 0xce4>; */ #dma-cells = <1>; }; + zynqmp_dpaud_setting: dp-aud@fd4ac000 { + compatible = "xlnx,zynqmp-dpaud-setting", "syscon"; + reg = <0x0 0xfd4ac000 0x0 0x1000>; + }; + zynqmp_dpsub: display@fd4a0000 { bootph-all; compatible = "xlnx,zynqmp-dpsub-1.7"; status = "disabled"; reg = <0x0 0xfd4a0000 0x0 0x1000>, <0x0 0xfd4aa000 0x0 0x1000>, - <0x0 0xfd4ab000 0x0 0x1000>, - <0x0 0xfd4ac000 0x0 0x1000>; - reg-names = "dp", "blend", "av_buf", "aud"; + <0x0 0xfd4ab000 0x0 0x1000>; + reg-names = "dp", "blend", "av_buf"; + xlnx,dpaud-reg = <&zynqmp_dpaud_setting>; interrupts = ; interrupt-parent = <&gic>; + /* iommus = <&smmu 0xce3>; */ clock-names = "dp_apb_clk", "dp_aud_clk", "dp_vtc_pixel_clk_in"; power-domains = <&zynqmp_firmware PD_DP>; @@ -1042,6 +1170,34 @@ <&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO2>, <&zynqmp_dpdma ZYNQMP_DPDMA_GRAPHICS>; + /* dummy node to indicate there's no child i2c device */ + i2c-bus { + }; + + zynqmp_dp_snd_codec0: zynqmp-dp-snd-codec0 { + compatible = "xlnx,dp-snd-codec"; + clock-names = "aud_clk"; + }; + + zynqmp_dp_snd_pcm0: zynqmp-dp-snd-pcm0 { + compatible = "xlnx,dp-snd-pcm0"; + dmas = <&zynqmp_dpdma 4>; + dma-names = "tx"; + }; + + zynqmp_dp_snd_pcm1: zynqmp-dp-snd-pcm1 { + compatible = "xlnx,dp-snd-pcm1"; + dmas = <&zynqmp_dpdma 5>; + dma-names = "tx"; + }; + + zynqmp_dp_snd_card0: zynqmp-dp-snd-card { + compatible = "xlnx,dp-snd-card"; + xlnx,dp-snd-pcm = <&zynqmp_dp_snd_pcm0>, + <&zynqmp_dp_snd_pcm1>; + xlnx,dp-snd-codec = <&zynqmp_dp_snd_codec0>; + }; + ports { #address-cells = <1>; #size-cells = <0>; --- linux-xilinx-6.8.0.orig/arch/arm64/configs/defconfig +++ linux-xilinx-6.8.0/arch/arm64/configs/defconfig @@ -632,6 +632,7 @@ CONFIG_GPIO_UNIPHIER=y CONFIG_GPIO_VISCONTI=y CONFIG_GPIO_WCD934X=m +CONFIG_GPIO_VF610=y CONFIG_GPIO_XGENE=y CONFIG_GPIO_XGENE_SB=y CONFIG_GPIO_MAX732X=y @@ -1559,6 +1560,7 @@ CONFIG_INTERCONNECT_QCOM_SC8280XP=y CONFIG_INTERCONNECT_QCOM_SDM845=y CONFIG_INTERCONNECT_QCOM_SDX75=y +CONFIG_INTERCONNECT_QCOM_SM6115=y CONFIG_INTERCONNECT_QCOM_SM8150=m CONFIG_INTERCONNECT_QCOM_SM8250=m CONFIG_INTERCONNECT_QCOM_SM8350=m --- linux-xilinx-6.8.0.orig/arch/arm64/configs/xilinx_defconfig +++ linux-xilinx-6.8.0/arch/arm64/configs/xilinx_defconfig @@ -0,0 +1,649 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_PROFILING=y +CONFIG_CRASH_DUMP=y +CONFIG_ARCH_ZYNQMP=y +CONFIG_ARM64_VA_BITS_48=y +CONFIG_NR_CPUS=16 +CONFIG_COMPAT=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPUFREQ_DT=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MEMORY_HOTPLUG=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_CMA=y +# CONFIG_ZONE_DMA is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_SYN_COOKIES=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_SNMP=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_MARK_T=y +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_MQPRIO=y +CONFIG_NET_SCH_SKBPRIO=y +CONFIG_NET_PKTGEN=y +CONFIG_CAN=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_LEDS=y +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIBCM203X=y +CONFIG_BT_HCIBPA10X=y +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +CONFIG_BT_ATH3K=y +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_REG_CELLULAR_HINTS=y +CONFIG_CFG80211_REG_RELAX_NO_IR=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESSAGE_TRACING=y +CONFIG_MAC80211_DEBUG_MENU=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=y +CONFIG_NET_9P=y +CONFIG_PCI=y +# CONFIG_VGA_ARB is not set +CONFIG_PCIE_XILINX=y +CONFIG_PCIE_XILINX_DMA_PL=y +CONFIG_PCIE_XILINX_NWL=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_ARM_SCMI_POWER_CONTROL=y +CONFIG_ZYNQMP_FIRMWARE_DEBUG=y +CONFIG_ZYNQMP_FIRMWARE_SECURE=y +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_ARASAN=y +CONFIG_MTD_NAND_ECC_SW_BCH=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_SRAM=y +CONFIG_XILINX_SDFEC=y +CONFIG_XILINX_AIE=y +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_TI_ST=y +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_CEVA=y +# CONFIG_ATA_SFF is not set +CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_MACB=y +CONFIG_XILINX_EMACLITE=y +CONFIG_XILINX_AXI_EMAC=y +CONFIG_AMD_PHY=y +CONFIG_ADIN_PHY=y +CONFIG_BROADCOM_PHY=y +CONFIG_BCM7XXX_PHY=y +CONFIG_BCM87XX_PHY=y +CONFIG_CICADA_PHY=y +CONFIG_DAVICOM_PHY=y +CONFIG_ICPLUS_PHY=y +CONFIG_LXT_PHY=y +CONFIG_LSI_ET1011C_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_NATIONAL_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_QSEMI_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_STE10XP=y +CONFIG_DP83848_PHY=y +CONFIG_DP83867_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_XILINX_PHY=y +CONFIG_XILINX_GMII2RGMII=y +CONFIG_CAN_XILINXCAN=y +CONFIG_USB_USBNET=y +CONFIG_WL18XX=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_AMBA_PL010=y +CONFIG_SERIAL_AMBA_PL010_CONSOLE=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_MAX310X=y +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_UARTLITE_NR_UARTS=16 +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y +# CONFIG_HW_RANDOM is not set +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_SPI=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA9541=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_CADENCE=y +CONFIG_I2C_XILINX=y +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=y +CONFIG_I3C=y +CONFIG_CDNS_I3C_MASTER=y +CONFIG_DW_I3C_MASTER=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_XILINX=y +CONFIG_SPI_ZYNQMP_GQSPI=y +CONFIG_PINCTRL=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_XILINX=y +CONFIG_GPIO_ZYNQ=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA9570=y +CONFIG_GPIO_TPS65086=y +CONFIG_POWER_RESET_LTC2952=y +CONFIG_SENSORS_IIO_HWMON=y +CONFIG_SENSORS_LM63=y +CONFIG_PMBUS=y +CONFIG_SENSORS_IR38064=y +CONFIG_SENSORS_IRPS5401=y +CONFIG_SENSORS_MAX20751=y +CONFIG_SENSORS_PWM_FAN=y +CONFIG_WATCHDOG=y +CONFIG_XILINX_WATCHDOG=y +CONFIG_XILINX_WINDOW_WATCHDOG=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_MFD_TPS65086=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_TPS65086=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_XILINX=y +CONFIG_VIDEO_XILINX_CSI2RXSS=y +CONFIG_VIDEO_XILINX_AXI4S_SWITCH=y +CONFIG_VIDEO_XILINX_CFA=y +CONFIG_VIDEO_XILINX_CRESAMPLE=y +CONFIG_VIDEO_XILINX_DEMOSAIC=y +CONFIG_VIDEO_XILINX_GAMMA=y +CONFIG_VIDEO_XILINX_HDMI21RXSS=y +CONFIG_VIDEO_XILINX_HLS=y +CONFIG_VIDEO_XILINX_ISP=y +CONFIG_VIDEO_XILINX_REMAPPER=y +CONFIG_VIDEO_XILINX_RGB2YUV=y +CONFIG_VIDEO_XILINX_SCALER=y +CONFIG_VIDEO_XILINX_SDIRXSS=y +CONFIG_VIDEO_XILINX_SWITCH=y +CONFIG_VIDEO_XILINX_TPG=y +CONFIG_VIDEO_XILINX_VPSS_CSC=y +CONFIG_VIDEO_XILINX_VPSS_SCALER=y +CONFIG_VIDEO_XILINX_DPRXSS=y +CONFIG_VIDEO_XILINX_SCD=y +CONFIG_VIDEO_XILINX_M2M=y +CONFIG_VIDEO_XILINX_AXI4S_BROADCASTER=y +CONFIG_VIDEO_XILINX_AXI4S_SUBSETCONV=y +CONFIG_VIDEO_IMX219=y +CONFIG_VIDEO_IMX274=y +# CONFIG_MEDIA_TUNER_E4000 is not set +# CONFIG_MEDIA_TUNER_FC0011 is not set +# CONFIG_MEDIA_TUNER_FC0012 is not set +# CONFIG_MEDIA_TUNER_FC0013 is not set +# CONFIG_MEDIA_TUNER_FC2580 is not set +# CONFIG_MEDIA_TUNER_IT913X is not set +# CONFIG_MEDIA_TUNER_M88RS6000T is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MSI001 is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2063 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MXL301RF is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_R820T is not set +# CONFIG_MEDIA_TUNER_SI2157 is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_TDA18250 is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_TUA9001 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC4000 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_DVB_M88DS3103 is not set +# CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_STB0899 is not set +# CONFIG_DVB_STB6100 is not set +# CONFIG_DVB_STV090x is not set +# CONFIG_DVB_STV0910 is not set +# CONFIG_DVB_STV6110x is not set +# CONFIG_DVB_STV6111 is not set +# CONFIG_DVB_DRXK is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set +# CONFIG_DVB_SI2165 is not set +# CONFIG_DVB_TDA18271C2DD is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24116 is not set +# CONFIG_DVB_CX24117 is not set +# CONFIG_DVB_CX24120 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_DS3000 is not set +# CONFIG_DVB_MB86A16 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_SI21XX is not set +# CONFIG_DVB_STB6000 is not set +# CONFIG_DVB_STV0288 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_STV0900 is not set +# CONFIG_DVB_STV6110 is not set +# CONFIG_DVB_TDA10071 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA8261 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TS2020 is not set +# CONFIG_DVB_TUA6100 is not set +# CONFIG_DVB_TUNER_CX24113 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_ZL10036 is not set +# CONFIG_DVB_ZL10039 is not set +# CONFIG_DVB_AF9013 is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_CXD2820R is not set +# CONFIG_DVB_CXD2841ER is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_DIB9000 is not set +# CONFIG_DVB_DRXD is not set +# CONFIG_DVB_EC100 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_RTL2830 is not set +# CONFIG_DVB_RTL2832 is not set +# CONFIG_DVB_RTL2832_SDR is not set +# CONFIG_DVB_S5H1432 is not set +# CONFIG_DVB_SI2168 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_STV0367 is not set +# CONFIG_DVB_TDA10048 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_ZD1301_DEMOD is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_CXD2880 is not set +# CONFIG_DVB_STV0297 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_AU8522_DTV is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LG2160 is not set +# CONFIG_DVB_LGDT3305 is not set +# CONFIG_DVB_LGDT3306A is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_MXL692 is not set +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_S5H1411 is not set +# CONFIG_DVB_DIB8000 is not set +# CONFIG_DVB_MB86A20S is not set +# CONFIG_DVB_S921 is not set +# CONFIG_DVB_MN88443X is not set +# CONFIG_DVB_TC90522 is not set +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_DVB_A8293 is not set +# CONFIG_DVB_AF9033 is not set +# CONFIG_DVB_ASCOT2E is not set +# CONFIG_DVB_ATBM8830 is not set +# CONFIG_DVB_HELENE is not set +# CONFIG_DVB_HORUS3A is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_ISL6423 is not set +# CONFIG_DVB_IX2505V is not set +# CONFIG_DVB_LGS8GL5 is not set +# CONFIG_DVB_LGS8GXX is not set +# CONFIG_DVB_LNBH25 is not set +# CONFIG_DVB_LNBH29 is not set +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_LNBP22 is not set +# CONFIG_DVB_M88RS2000 is not set +# CONFIG_DVB_TDA665x is not set +# CONFIG_DVB_DRX39XYJ is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_DVB_SP2 is not set +CONFIG_DRM=y +CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM=y +CONFIG_DRM_ZYNQMP_DPSUB=y +CONFIG_DRM_XLNX=y +CONFIG_DRM_XLNX_BRIDGE=y +CONFIG_DRM_XLNX_BRIDGE_DEBUG_FS=y +CONFIG_DRM_XLNX_DPTX=y +CONFIG_DRM_XLNX_DSI=y +CONFIG_DRM_XLNX_HDMITX=y +CONFIG_DRM_XLNX_MIXER=y +CONFIG_DRM_XLNX_PL_DISP=y +CONFIG_DRM_XLNX_SDI=y +CONFIG_DRM_XLNX_BRIDGE_CSC=y +CONFIG_DRM_XLNX_BRIDGE_SCALER=y +CONFIG_DRM_XLNX_BRIDGE_VTC=y +CONFIG_FB=y +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_PCI is not set +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_XILINX_DP=y +CONFIG_SND_SOC_XILINX_SDI=y +CONFIG_SND_SOC_XILINX_I2S=y +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=y +CONFIG_SND_SOC_XILINX_SPDIF=y +CONFIG_SND_SOC_XILINX_PL_SND_CARD=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_OTG=y +CONFIG_USB_OTG_FSM=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_ULPI=y +CONFIG_USB_USB2244=m +CONFIG_USB_USB5744=m +CONFIG_USB_ONBOARD_DEV=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_XILINX=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_ETH=m +CONFIG_USB_ETH_EEM=y +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_SCSI_UFSHCD=y +CONFIG_SCSI_UFS_BSG=y +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_AMD_VERSAL2=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=y +CONFIG_LEDS_TRIGGER_CAMERA=y +CONFIG_EDAC=y +CONFIG_EDAC_SYNOPSYS=y +CONFIG_EDAC_XILINX_XILSEM=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_ZYNQMP=y +CONFIG_DMADEVICES=y +CONFIG_XILINX_DMA=y +CONFIG_XILINX_ZYNQMP_DMA=y +CONFIG_XILINX_ZYNQMP_DPDMA=y +CONFIG_DMATEST=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_UIO=y +CONFIG_UIO_XILINX_APM=y +CONFIG_UIO_XILINX_AI_ENGINE=m +CONFIG_VFIO=y +CONFIG_VFIO_CDX=y +CONFIG_STAGING=y +CONFIG_XILINX_FCLK=y +CONFIG_XLNX_SYNC=y +CONFIG_SERIAL_UARTLITE_RS485=y +CONFIG_AXIENET_HAS_TADMA=y +CONFIG_XILINX_TSN=y +CONFIG_COMMON_CLK_SCMI=y +CONFIG_COMMON_CLK_SI5341=y +CONFIG_COMMON_CLK_SI570=y +CONFIG_COMMON_CLK_SI5324=y +CONFIG_COMMON_CLK_VC7=y +CONFIG_COMMON_CLK_PROXO=y +CONFIG_XILINX_VCU=m +CONFIG_COMMON_CLK_XLNX_CLKWZRD=y +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set +# CONFIG_FSL_ERRATUM_A008585 is not set +CONFIG_ARM_SMMU_V3=y +CONFIG_ZYNQMP_R5_REMOTEPROC=m +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_CTRL=y +CONFIG_RPMSG_VIRTIO=y +CONFIG_IIO=y +CONFIG_INA2XX_ADC=y +CONFIG_INA260_ADC=y +CONFIG_XILINX_XADC=y +CONFIG_XILINX_AMS=y +CONFIG_VERSAL_SYSMON=y +CONFIG_BME680=y +CONFIG_BMG160=y +CONFIG_IIO_ST_LSM6DSX=y +CONFIG_BMC150_MAGN_SPI=y +CONFIG_PWM=y +CONFIG_PWM_CADENCE=y +CONFIG_XILINX_INTC=y +CONFIG_IRQCHIP_XILINX_INTC_MODULE_SUPPORT_EXPERIMENTAL=y +CONFIG_RESET_CONTROLLER=y +CONFIG_PHY_XILINX_ZYNQMP=y +CONFIG_PHY_XILINX_HDMIPHY=y +CONFIG_ARM_CCI_PMU=y +CONFIG_RAS=y +CONFIG_NVMEM_ZYNQMP=y +CONFIG_XLNX_SEC_CFG=y +CONFIG_FPGA=y +CONFIG_XILINX_AFI_FPGA=y +CONFIG_XILINX_PR_DECOUPLER=y +CONFIG_FPGA_REGION=y +CONFIG_OF_FPGA_REGION=y +CONFIG_FPGA_MGR_ZYNQMP_FPGA=y +CONFIG_FPGA_MGR_VERSAL_FPGA=y +CONFIG_CDX_BUS=y +CONFIG_CDX_CONTROLLER=m +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=y +CONFIG_EXPORTFS_BLOCK_OPS=y +CONFIG_QUOTA=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS_FS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_ECRYPT_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RUBIN=y +CONFIG_UBIFS_FS=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set +CONFIG_NFSD=y +CONFIG_NFSD_V4=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +CONFIG_CRYPTO_SHA3_ARM64=y +CONFIG_CRYPTO_SM3_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_BS=y +CONFIG_CRYPTO_SM4_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_DEV_XILINX_ECDSA=y +CONFIG_CRYPTO_DEV_ZYNQMP_AES=y +CONFIG_CRYPTO_DEV_ZYNQMP_SHA3=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=256 +CONFIG_PRINTK_TIME=y +# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_MEMTEST=y --- linux-xilinx-6.8.0.orig/arch/arm64/configs/xilinx_versal_defconfig +++ linux-xilinx-6.8.0/arch/arm64/configs/xilinx_versal_defconfig @@ -0,0 +1,401 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_PERF_EVENTS=y +CONFIG_ARCH_ZYNQMP=y +CONFIG_ARM64_VA_BITS_48=y +CONFIG_NR_CPUS=2 +CONFIG_COMPAT=y +CONFIG_RANDOMIZE_BASE=y +# CONFIG_EFI is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPUFREQ_DT=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPACTION is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_CMA=y +# CONFIG_ZONE_DMA is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_SYN_COOKIES=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_SNMP=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_MARK_T=y +CONFIG_BRIDGE=y +CONFIG_NET_PKTGEN=y +CONFIG_CAN=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_ZYNQMP_FIRMWARE_DEBUG=y +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_SRAM=y +CONFIG_XILINX_AIE=y +CONFIG_EEPROM_AT24=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_MACB=y +CONFIG_MARVELL_PHY=y +CONFIG_MICROSEMI_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_DP83848_PHY=y +CONFIG_DP83867_PHY=y +CONFIG_CAN_XILINXCAN=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_AMBA_PL010=y +CONFIG_SERIAL_AMBA_PL010_CONSOLE=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_CADENCE=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_XILINX=y +CONFIG_SPI_ZYNQMP_GQSPI=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_ZYNQ=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_XILINX_WATCHDOG=y +CONFIG_XILINX_WINDOW_WATCHDOG=y +CONFIG_REGULATOR=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_XILINX=y +CONFIG_VIDEO_XILINX_CSI2RXSS=y +CONFIG_VIDEO_XILINX_AXI4S_SWITCH=y +CONFIG_VIDEO_XILINX_CFA=y +CONFIG_VIDEO_XILINX_CRESAMPLE=y +CONFIG_VIDEO_XILINX_DEMOSAIC=y +CONFIG_VIDEO_XILINX_GAMMA=y +CONFIG_VIDEO_XILINX_HDMI21RXSS=y +CONFIG_VIDEO_XILINX_HLS=y +CONFIG_VIDEO_XILINX_ISP=y +CONFIG_VIDEO_XILINX_REMAPPER=y +CONFIG_VIDEO_XILINX_RGB2YUV=y +CONFIG_VIDEO_XILINX_SCALER=y +CONFIG_VIDEO_XILINX_SDIRXSS=y +CONFIG_VIDEO_XILINX_SWITCH=y +CONFIG_VIDEO_XILINX_TPG=y +CONFIG_VIDEO_XILINX_VPSS_CSC=y +CONFIG_VIDEO_XILINX_VPSS_SCALER=y +CONFIG_VIDEO_XILINX_DPRXSS=y +CONFIG_VIDEO_XILINX_SCD=y +CONFIG_VIDEO_XILINX_M2M=y +# CONFIG_MEDIA_TUNER_E4000 is not set +# CONFIG_MEDIA_TUNER_FC0011 is not set +# CONFIG_MEDIA_TUNER_FC0012 is not set +# CONFIG_MEDIA_TUNER_FC0013 is not set +# CONFIG_MEDIA_TUNER_FC2580 is not set +# CONFIG_MEDIA_TUNER_IT913X is not set +# CONFIG_MEDIA_TUNER_M88RS6000T is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MSI001 is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2063 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MXL301RF is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_R820T is not set +# CONFIG_MEDIA_TUNER_SI2157 is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_TDA18250 is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_TUA9001 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC4000 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_STB0899 is not set +# CONFIG_DVB_STB6100 is not set +# CONFIG_DVB_STV090x is not set +# CONFIG_DVB_STV0910 is not set +# CONFIG_DVB_STV6110x is not set +# CONFIG_DVB_STV6111 is not set +# CONFIG_DVB_DRXK is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set +# CONFIG_DVB_SI2165 is not set +# CONFIG_DVB_TDA18271C2DD is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24116 is not set +# CONFIG_DVB_CX24117 is not set +# CONFIG_DVB_CX24120 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_DS3000 is not set +# CONFIG_DVB_MB86A16 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_SI21XX is not set +# CONFIG_DVB_STB6000 is not set +# CONFIG_DVB_STV0288 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_STV0900 is not set +# CONFIG_DVB_STV6110 is not set +# CONFIG_DVB_TDA10071 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA8261 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TS2020 is not set +# CONFIG_DVB_TUA6100 is not set +# CONFIG_DVB_TUNER_CX24113 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_ZL10036 is not set +# CONFIG_DVB_ZL10039 is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_CXD2820R is not set +# CONFIG_DVB_CXD2841ER is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_DIB9000 is not set +# CONFIG_DVB_DRXD is not set +# CONFIG_DVB_EC100 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_S5H1432 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_STV0367 is not set +# CONFIG_DVB_TDA10048 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_ZD1301_DEMOD is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_CXD2880 is not set +# CONFIG_DVB_STV0297 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_AU8522_DTV is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LG2160 is not set +# CONFIG_DVB_LGDT3305 is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_MXL692 is not set +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_S5H1411 is not set +# CONFIG_DVB_DIB8000 is not set +# CONFIG_DVB_MB86A20S is not set +# CONFIG_DVB_S921 is not set +# CONFIG_DVB_MN88443X is not set +# CONFIG_DVB_TC90522 is not set +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_DVB_A8293 is not set +# CONFIG_DVB_AF9033 is not set +# CONFIG_DVB_ASCOT2E is not set +# CONFIG_DVB_ATBM8830 is not set +# CONFIG_DVB_HELENE is not set +# CONFIG_DVB_HORUS3A is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_ISL6423 is not set +# CONFIG_DVB_IX2505V is not set +# CONFIG_DVB_LGS8GL5 is not set +# CONFIG_DVB_LGS8GXX is not set +# CONFIG_DVB_LNBH25 is not set +# CONFIG_DVB_LNBH29 is not set +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_LNBP22 is not set +# CONFIG_DVB_M88RS2000 is not set +# CONFIG_DVB_TDA665x is not set +# CONFIG_DVB_DRX39XYJ is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_DVB_SP2 is not set +CONFIG_DRM=y +CONFIG_DRM_XLNX=y +CONFIG_DRM_XLNX_BRIDGE=y +CONFIG_DRM_XLNX_BRIDGE_DEBUG_FS=y +CONFIG_DRM_XLNX_DPTX=y +CONFIG_DRM_XLNX_DSI=y +CONFIG_DRM_XLNX_HDMITX=y +CONFIG_DRM_XLNX_MIXER=y +CONFIG_DRM_XLNX_PL_DISP=y +CONFIG_DRM_XLNX_SDI=y +CONFIG_DRM_XLNX_BRIDGE_CSC=y +CONFIG_DRM_XLNX_BRIDGE_SCALER=y +CONFIG_DRM_XLNX_BRIDGE_VTC=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_OTG=y +CONFIG_USB_OTG_FSM=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_ETH=m +CONFIG_USB_ETH_EEM=y +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_EDAC=y +CONFIG_EDAC_XILINX_XILSEM=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_ZYNQMP=y +CONFIG_DMADEVICES=y +CONFIG_XILINX_ZYNQMP_DMA=y +CONFIG_DMATEST=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_DMEM_GENIRQ=m +CONFIG_STAGING=y +CONFIG_COMMON_CLK_XLNX_CLKWZRD=y +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set +# CONFIG_FSL_ERRATUM_A008585 is not set +CONFIG_REMOTEPROC=y +CONFIG_ZYNQMP_R5_REMOTEPROC=m +CONFIG_RPMSG_CHAR=m +CONFIG_IIO=y +CONFIG_VERSAL_SYSMON=y +CONFIG_XILINX_INTC=y +CONFIG_RESET_CONTROLLER=y +CONFIG_PHY_XILINX_ZYNQMP=y +CONFIG_PHY_XILINX_HDMIPHY=y +CONFIG_ARM_CCI_PMU=y +CONFIG_RAS=y +CONFIG_XLNX_SEC_CFG=y +CONFIG_FPGA=y +CONFIG_XILINX_PR_DECOUPLER=y +CONFIG_FPGA_REGION=y +CONFIG_OF_FPGA_REGION=y +CONFIG_FPGA_MGR_VERSAL_FPGA=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=y +CONFIG_EXPORTFS_BLOCK_OPS=y +CONFIG_QUOTA=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_ECRYPT_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RUBIN=y +CONFIG_UBIFS_FS=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_DEV_XILINX_ECDSA=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=256 +CONFIG_PRINTK_TIME=y +# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_MEMTEST=y --- linux-xilinx-6.8.0.orig/arch/arm64/configs/xilinx_versal_net_defconfig +++ linux-xilinx-6.8.0/arch/arm64/configs/xilinx_versal_net_defconfig @@ -0,0 +1,198 @@ +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_RCU_EXPERT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_PERF_EVENTS=y +CONFIG_ARCH_ZYNQMP=y +CONFIG_ARM64_VA_BITS_48=y +CONFIG_NR_CPUS=16 +# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set +# CONFIG_ARM64_TAGGED_ADDR_ABI is not set +CONFIG_COMPAT=y +# CONFIG_ARM64_SVE is not set +CONFIG_RANDOMIZE_BASE=y +# CONFIG_EFI is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPACTION is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=y +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_SYN_COOKIES=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_DNS_RESOLVER=y +CONFIG_VSOCKETS=y +CONFIG_QRTR=y +CONFIG_CAN=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_ZYNQMP_FIRMWARE_DEBUG=y +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_SPI_NOR_SWP_DISABLE=y +CONFIG_OF_OVERLAY=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_SRAM=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_MACB=y +CONFIG_ADIN_PHY=y +CONFIG_DAVICOM_PHY=y +CONFIG_DP83822_PHY=y +CONFIG_DP83TC811_PHY=y +CONFIG_DP83848_PHY=y +CONFIG_DP83867_PHY=y +CONFIG_DP83869_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_XILINX_PHY=y +CONFIG_XILINX_GMII2RGMII=y +CONFIG_CAN_XILINXCAN=y +CONFIG_CAN_DEBUG_DEVICES=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_SERIAL_AMBA_PL010=y +CONFIG_SERIAL_AMBA_PL010_CONSOLE=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_CADENCE=y +CONFIG_I2C_XILINX=y +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=y +CONFIG_I3C=y +CONFIG_CDNS_I3C_MASTER=y +CONFIG_DW_I3C_MASTER=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_CADENCE_QUADSPI=y +CONFIG_SPI_XILINX=y +CONFIG_SPI_ZYNQMP_GQSPI=y +CONFIG_PTP_1588_CLOCK_XILINX=y +CONFIG_GPIOLIB=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_XILINX_WATCHDOG=y +CONFIG_XILINX_WINDOW_WATCHDOG=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_REGULATOR=y +CONFIG_FB=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_OTG_FSM=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DBGCAP=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_ULPI=y +CONFIG_USB_HUB_USB251XB=y +CONFIG_USB_USB5744=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_XILINX=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_ETH=m +CONFIG_USB_ETH_EEM=y +CONFIG_USB_MASS_STORAGE=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_ZYNQMP=y +CONFIG_RTC_DRV_CADENCE=y +CONFIG_DMADEVICES=y +CONFIG_XILINX_ZYNQMP_DMA=y +CONFIG_DMATEST=y +CONFIG_SYNC_FILE=y +CONFIG_VFIO=y +CONFIG_VFIO_CDX=y +# CONFIG_VIRTIO_MENU is not set +# CONFIG_VHOST_MENU is not set +CONFIG_COMMON_CLK_XLNX_CLKWZRD=y +# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set +# CONFIG_FSL_ERRATUM_A008585 is not set +CONFIG_ARM_SMMU_V3=y +CONFIG_REMOTEPROC_CDEV=y +CONFIG_ZYNQMP_R5_REMOTEPROC=m +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_CTRL=y +CONFIG_RPMSG_VIRTIO=y +CONFIG_IIO=y +CONFIG_IIO_ST_LSM6DSX=y +CONFIG_RESET_CONTROLLER=y +CONFIG_PHY_XILINX_ZYNQMP=y +# CONFIG_ARM_PMU is not set +CONFIG_CDX_BUS=y +CONFIG_CDX_CONTROLLER=m +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=y +CONFIG_EXPORTFS_BLOCK_OPS=y +# CONFIG_DNOTIFY is not set +CONFIG_QUOTA=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_ECRYPT_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_SUMMARY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RUBIN=y +CONFIG_CRAMFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_KEYS=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=256 +CONFIG_PRINTK_TIME=y +# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set +CONFIG_DEBUG_FS=y +CONFIG_RCU_CPU_STALL_TIMEOUT=80 +# CONFIG_STRICT_DEVMEM is not set +CONFIG_MEMTEST=y --- linux-xilinx-6.8.0.orig/arch/arm64/configs/xilinx_zynqmp_defconfig +++ linux-xilinx-6.8.0/arch/arm64/configs/xilinx_zynqmp_defconfig @@ -0,0 +1,579 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_PROFILING=y +CONFIG_ARCH_ZYNQMP=y +CONFIG_NR_CPUS=4 +CONFIG_COMPAT=y +CONFIG_RANDOMIZE_BASE=y +# CONFIG_DMI is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPUFREQ_DT=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MEMORY_HOTPLUG=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_CMA=y +# CONFIG_ZONE_DMA is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_SYN_COOKIES=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_T_FILTER=y +CONFIG_BRIDGE_EBT_T_NAT=y +CONFIG_BRIDGE_EBT_MARK_T=y +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_MQPRIO=y +CONFIG_NET_SCH_SKBPRIO=y +CONFIG_NET_PKTGEN=y +CONFIG_CAN=y +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_LEDS=y +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIBTSDIO=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIBCM203X=y +CONFIG_BT_HCIBPA10X=y +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +CONFIG_BT_ATH3K=y +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_CERTIFICATION_ONUS=y +CONFIG_CFG80211_REG_CELLULAR_HINTS=y +CONFIG_CFG80211_REG_RELAX_NO_IR=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESSAGE_TRACING=y +CONFIG_MAC80211_DEBUG_MENU=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=y +CONFIG_NET_9P=y +CONFIG_PCI=y +# CONFIG_VGA_ARB is not set +CONFIG_PCIE_XILINX_NWL=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_CONNECTOR=y +CONFIG_ZYNQMP_FIRMWARE_DEBUG=y +CONFIG_ZYNQMP_FIRMWARE_SECURE=y +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_DATAFLASH=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_NAND_ARASAN=y +CONFIG_MTD_NAND_ECC_SW_BCH=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_MTD_UBI=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_CONFIGFS=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_XILINX_SDFEC=y +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT25=y +CONFIG_TI_ST=y +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_AHCI_CEVA=y +# CONFIG_ATA_SFF is not set +CONFIG_NETDEVICES=y +CONFIG_TUN=y +CONFIG_MACB=y +CONFIG_XILINX_EMACLITE=y +CONFIG_XILINX_AXI_EMAC=y +CONFIG_AMD_PHY=y +CONFIG_BROADCOM_PHY=y +CONFIG_BCM7XXX_PHY=y +CONFIG_BCM87XX_PHY=y +CONFIG_CICADA_PHY=y +CONFIG_DAVICOM_PHY=y +CONFIG_ICPLUS_PHY=y +CONFIG_LXT_PHY=y +CONFIG_LSI_ET1011C_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_MICREL_PHY=y +CONFIG_NATIONAL_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_QSEMI_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_STE10XP=y +CONFIG_DP83867_PHY=y +CONFIG_VITESSE_PHY=y +CONFIG_XILINX_GMII2RGMII=y +CONFIG_CAN_XILINXCAN=y +CONFIG_USB_USBNET=y +CONFIG_WL18XX=m +CONFIG_WLCORE_SPI=m +CONFIG_WLCORE_SDIO=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_MAX310X=y +CONFIG_SERIAL_UARTLITE=y +CONFIG_SERIAL_UARTLITE_CONSOLE=y +CONFIG_SERIAL_UARTLITE_NR_UARTS=16 +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y +# CONFIG_HW_RANDOM is not set +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_SPI=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_CADENCE=y +CONFIG_I2C_XILINX=y +CONFIG_I2C_SLAVE=y +CONFIG_I2C_SLAVE_EEPROM=y +CONFIG_SPI=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_XILINX=y +CONFIG_SPI_ZYNQMP_GQSPI=y +CONFIG_PINCTRL=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_XILINX=y +CONFIG_GPIO_ZYNQ=y +CONFIG_GPIO_PCA953X=y +CONFIG_GPIO_PCA9570=y +CONFIG_GPIO_TPS65086=y +CONFIG_POWER_RESET_LTC2952=y +CONFIG_SENSORS_IIO_HWMON=y +CONFIG_SENSORS_LM63=y +CONFIG_PMBUS=y +CONFIG_SENSORS_IRPS5401=y +CONFIG_SENSORS_MAX20751=y +CONFIG_SENSORS_PWM_FAN=y +CONFIG_WATCHDOG=y +CONFIG_XILINX_WATCHDOG=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_MFD_TPS65086=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_TPS65086=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_XILINX=y +CONFIG_VIDEO_XILINX_CSI2RXSS=y +CONFIG_VIDEO_XILINX_AXI4S_SWITCH=y +CONFIG_VIDEO_XILINX_CFA=y +CONFIG_VIDEO_XILINX_CRESAMPLE=y +CONFIG_VIDEO_XILINX_DEMOSAIC=y +CONFIG_VIDEO_XILINX_GAMMA=y +CONFIG_VIDEO_XILINX_HDMI21RXSS=y +CONFIG_VIDEO_XILINX_HLS=y +CONFIG_VIDEO_XILINX_ISP=y +CONFIG_VIDEO_XILINX_REMAPPER=y +CONFIG_VIDEO_XILINX_RGB2YUV=y +CONFIG_VIDEO_XILINX_SCALER=y +CONFIG_VIDEO_XILINX_SDIRXSS=y +CONFIG_VIDEO_XILINX_SWITCH=y +CONFIG_VIDEO_XILINX_TPG=y +CONFIG_VIDEO_XILINX_VPSS_CSC=y +CONFIG_VIDEO_XILINX_VPSS_SCALER=y +CONFIG_VIDEO_XILINX_DPRXSS=y +CONFIG_VIDEO_XILINX_SCD=y +CONFIG_VIDEO_XILINX_M2M=y +CONFIG_VIDEO_XILINX_AXI4S_BROADCASTER=y +CONFIG_VIDEO_XILINX_AXI4S_SUBSETCONV=y +CONFIG_VIDEO_IMX219=y +CONFIG_VIDEO_IMX274=y +# CONFIG_MEDIA_TUNER_E4000 is not set +# CONFIG_MEDIA_TUNER_FC0011 is not set +# CONFIG_MEDIA_TUNER_FC0012 is not set +# CONFIG_MEDIA_TUNER_FC0013 is not set +# CONFIG_MEDIA_TUNER_FC2580 is not set +# CONFIG_MEDIA_TUNER_IT913X is not set +# CONFIG_MEDIA_TUNER_M88RS6000T is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MSI001 is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2063 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MXL301RF is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_R820T is not set +# CONFIG_MEDIA_TUNER_SI2157 is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_TDA18250 is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_TUA9001 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC4000 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_DVB_M88DS3103 is not set +# CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_STB0899 is not set +# CONFIG_DVB_STB6100 is not set +# CONFIG_DVB_STV090x is not set +# CONFIG_DVB_STV0910 is not set +# CONFIG_DVB_STV6110x is not set +# CONFIG_DVB_STV6111 is not set +# CONFIG_DVB_DRXK is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set +# CONFIG_DVB_SI2165 is not set +# CONFIG_DVB_TDA18271C2DD is not set +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24116 is not set +# CONFIG_DVB_CX24117 is not set +# CONFIG_DVB_CX24120 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_DS3000 is not set +# CONFIG_DVB_MB86A16 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_SI21XX is not set +# CONFIG_DVB_STB6000 is not set +# CONFIG_DVB_STV0288 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_STV0900 is not set +# CONFIG_DVB_STV6110 is not set +# CONFIG_DVB_TDA10071 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA8261 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TS2020 is not set +# CONFIG_DVB_TUA6100 is not set +# CONFIG_DVB_TUNER_CX24113 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_ZL10036 is not set +# CONFIG_DVB_ZL10039 is not set +# CONFIG_DVB_AF9013 is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_CXD2820R is not set +# CONFIG_DVB_CXD2841ER is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_DIB9000 is not set +# CONFIG_DVB_DRXD is not set +# CONFIG_DVB_EC100 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_RTL2830 is not set +# CONFIG_DVB_RTL2832 is not set +# CONFIG_DVB_RTL2832_SDR is not set +# CONFIG_DVB_S5H1432 is not set +# CONFIG_DVB_SI2168 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_STV0367 is not set +# CONFIG_DVB_TDA10048 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_ZD1301_DEMOD is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_CXD2880 is not set +# CONFIG_DVB_STV0297 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_AU8522_DTV is not set +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LG2160 is not set +# CONFIG_DVB_LGDT3305 is not set +# CONFIG_DVB_LGDT3306A is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_MXL692 is not set +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_S5H1411 is not set +# CONFIG_DVB_DIB8000 is not set +# CONFIG_DVB_MB86A20S is not set +# CONFIG_DVB_S921 is not set +# CONFIG_DVB_MN88443X is not set +# CONFIG_DVB_TC90522 is not set +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_DVB_A8293 is not set +# CONFIG_DVB_AF9033 is not set +# CONFIG_DVB_ASCOT2E is not set +# CONFIG_DVB_ATBM8830 is not set +# CONFIG_DVB_HELENE is not set +# CONFIG_DVB_HORUS3A is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +# CONFIG_DVB_ISL6423 is not set +# CONFIG_DVB_IX2505V is not set +# CONFIG_DVB_LGS8GL5 is not set +# CONFIG_DVB_LGS8GXX is not set +# CONFIG_DVB_LNBH25 is not set +# CONFIG_DVB_LNBH29 is not set +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_LNBP22 is not set +# CONFIG_DVB_M88RS2000 is not set +# CONFIG_DVB_TDA665x is not set +# CONFIG_DVB_DRX39XYJ is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_DVB_SP2 is not set +CONFIG_DRM=y +CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM=y +CONFIG_DRM_ZYNQMP_DPSUB=y +CONFIG_DRM_XLNX=y +CONFIG_DRM_XLNX_BRIDGE=y +CONFIG_DRM_XLNX_BRIDGE_DEBUG_FS=y +CONFIG_DRM_XLNX_DPTX=y +CONFIG_DRM_XLNX_DSI=y +CONFIG_DRM_XLNX_HDMITX=y +CONFIG_DRM_XLNX_MIXER=y +CONFIG_DRM_XLNX_PL_DISP=y +CONFIG_DRM_XLNX_SDI=y +CONFIG_DRM_XLNX_BRIDGE_CSC=y +CONFIG_DRM_XLNX_BRIDGE_SCALER=y +CONFIG_DRM_XLNX_BRIDGE_VTC=y +CONFIG_FB=y +CONFIG_SOUND=y +CONFIG_SND=y +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_PCI is not set +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_XILINX_DP=y +CONFIG_SND_SOC_XILINX_SDI=y +CONFIG_SND_SOC_XILINX_I2S=y +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=y +CONFIG_SND_SOC_XILINX_SPDIF=y +CONFIG_SND_SOC_XILINX_PL_SND_CARD=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_OTG=y +CONFIG_USB_OTG_FSM=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_ULPI=y +CONFIG_USB_USB2244=m +CONFIG_USB_USB5744=m +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_XILINX=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_ETH=m +CONFIG_USB_ETH_EEM=y +CONFIG_USB_MASS_STORAGE=m +CONFIG_USB_G_SERIAL=m +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_TRANSIENT=y +CONFIG_LEDS_TRIGGER_CAMERA=y +CONFIG_EDAC=y +CONFIG_EDAC_SYNOPSYS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_ZYNQMP=y +CONFIG_DMADEVICES=y +CONFIG_XILINX_DMA=y +CONFIG_XILINX_ZYNQMP_DMA=y +CONFIG_XILINX_ZYNQMP_DPDMA=y +CONFIG_DMATEST=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_DMEM_GENIRQ=m +CONFIG_UIO_XILINX_APM=y +CONFIG_STAGING=y +CONFIG_XILINX_FCLK=y +CONFIG_XLNX_SYNC=y +CONFIG_SERIAL_UARTLITE_RS485=y +CONFIG_AXIENET_HAS_TADMA=y +CONFIG_XILINX_TSN=y +CONFIG_COMMON_CLK_SI5341=y +CONFIG_COMMON_CLK_SI570=y +CONFIG_COMMON_CLK_SI5324=y +CONFIG_COMMON_CLK_VC7=y +CONFIG_COMMON_CLK_PROXO=y +CONFIG_XILINX_VCU=m +CONFIG_COMMON_CLK_XLNX_CLKWZRD=y +CONFIG_REMOTEPROC=y +CONFIG_ZYNQMP_R5_REMOTEPROC=m +CONFIG_RPMSG_CHAR=m +CONFIG_IIO=y +CONFIG_INA2XX_ADC=y +CONFIG_INA260_ADC=y +CONFIG_XILINX_XADC=y +CONFIG_XILINX_AMS=y +CONFIG_BME680=y +CONFIG_BMG160=y +CONFIG_BMC150_MAGN_SPI=y +CONFIG_PWM=y +CONFIG_PWM_CADENCE=y +CONFIG_XILINX_INTC=y +CONFIG_RESET_CONTROLLER=y +CONFIG_PHY_XILINX_ZYNQMP=y +CONFIG_PHY_XILINX_HDMIPHY=y +CONFIG_ARM_CCI_PMU=y +CONFIG_RAS=y +CONFIG_NVMEM_ZYNQMP=y +CONFIG_FPGA=y +CONFIG_XILINX_AFI_FPGA=y +CONFIG_FPGA_BRIDGE=y +CONFIG_XILINX_PR_DECOUPLER=y +CONFIG_FPGA_REGION=y +CONFIG_OF_FPGA_REGION=y +CONFIG_FPGA_MGR_ZYNQMP_FPGA=y +CONFIG_EXT3_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=y +CONFIG_QUOTA=y +CONFIG_QFMT_V2=y +CONFIG_AUTOFS_FS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_ECRYPT_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RUBIN=y +CONFIG_UBIFS_FS=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_DEV_XILINX_RSA=y +CONFIG_CRYPTO_DEV_ZYNQMP_AES=y +CONFIG_CRYPTO_DEV_ZYNQMP_SHA3=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=256 +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +# CONFIG_STRICT_DEVMEM is not set +CONFIG_MEMTEST=y --- linux-xilinx-6.8.0.orig/arch/arm64/include/asm/asm-bug.h +++ linux-xilinx-6.8.0/arch/arm64/include/asm/asm-bug.h @@ -28,6 +28,7 @@ 14470: .long 14471f - .; \ _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ .short flags; \ + .align 2; \ .popsection; \ 14471: #else --- linux-xilinx-6.8.0.orig/arch/arm64/include/asm/irqflags.h +++ linux-xilinx-6.8.0/arch/arm64/include/asm/irqflags.h @@ -5,7 +5,6 @@ #ifndef __ASM_IRQFLAGS_H #define __ASM_IRQFLAGS_H -#include #include #include #include --- linux-xilinx-6.8.0.orig/arch/arm64/include/asm/sysreg.h +++ linux-xilinx-6.8.0/arch/arm64/include/asm/sysreg.h @@ -1036,18 +1036,18 @@ * Permission Indirection Extension (PIE) permission encodings. * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension). */ -#define PIE_NONE_O 0x0 -#define PIE_R_O 0x1 -#define PIE_X_O 0x2 -#define PIE_RX_O 0x3 -#define PIE_RW_O 0x5 -#define PIE_RWnX_O 0x6 -#define PIE_RWX_O 0x7 -#define PIE_R 0x8 -#define PIE_GCS 0x9 -#define PIE_RX 0xa -#define PIE_RW 0xc -#define PIE_RWX 0xe +#define PIE_NONE_O UL(0x0) +#define PIE_R_O UL(0x1) +#define PIE_X_O UL(0x2) +#define PIE_RX_O UL(0x3) +#define PIE_RW_O UL(0x5) +#define PIE_RWnX_O UL(0x6) +#define PIE_RWX_O UL(0x7) +#define PIE_R UL(0x8) +#define PIE_GCS UL(0x9) +#define PIE_RX UL(0xa) +#define PIE_RW UL(0xc) +#define PIE_RWX UL(0xe) #define PIRx_ELx_PERM(idx, perm) ((perm) << ((idx) * 4)) --- linux-xilinx-6.8.0.orig/arch/arm64/include/asm/tlbflush.h +++ linux-xilinx-6.8.0/arch/arm64/include/asm/tlbflush.h @@ -161,12 +161,18 @@ #define MAX_TLBI_RANGE_PAGES __TLBI_RANGE_PAGES(31, 3) /* - * Generate 'num' values from -1 to 30 with -1 rejected by the - * __flush_tlb_range() loop below. - */ -#define TLBI_RANGE_MASK GENMASK_ULL(4, 0) -#define __TLBI_RANGE_NUM(pages, scale) \ - ((((pages) >> (5 * (scale) + 1)) & TLBI_RANGE_MASK) - 1) + * Generate 'num' values from -1 to 31 with -1 rejected by the + * __flush_tlb_range() loop below. Its return value is only + * significant for a maximum of MAX_TLBI_RANGE_PAGES pages. If + * 'pages' is more than that, you must iterate over the overall + * range. + */ +#define __TLBI_RANGE_NUM(pages, scale) \ + ({ \ + int __pages = min((pages), \ + __TLBI_RANGE_PAGES(31, (scale))); \ + (__pages >> (5 * (scale) + 1)) - 1; \ + }) /* * TLB Invalidation @@ -379,10 +385,6 @@ * 3. If there is 1 page remaining, flush it through non-range operations. Range * operations can only span an even number of pages. We save this for last to * ensure 64KB start alignment is maintained for the LPA2 case. - * - * Note that certain ranges can be represented by either num = 31 and - * scale or num = 0 and scale + 1. The loop below favours the latter - * since num is limited to 30 by the __TLBI_RANGE_NUM() macro. */ #define __flush_tlb_range_op(op, start, pages, stride, \ asid, tlb_level, tlbi_user, lpa2) \ --- linux-xilinx-6.8.0.orig/arch/arm64/include/asm/unistd32.h +++ linux-xilinx-6.8.0/arch/arm64/include/asm/unistd32.h @@ -840,7 +840,7 @@ #define __NR_ppoll_time64 414 __SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64) #define __NR_io_pgetevents_time64 416 -__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents) +__SYSCALL(__NR_io_pgetevents_time64, compat_sys_io_pgetevents_time64) #define __NR_recvmmsg_time64 417 __SYSCALL(__NR_recvmmsg_time64, compat_sys_recvmmsg_time64) #define __NR_mq_timedsend_time64 418 --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/armv8_deprecated.c +++ linux-xilinx-6.8.0/arch/arm64/kernel/armv8_deprecated.c @@ -462,6 +462,9 @@ for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) { struct insn_emulation *insn = insn_emulations[i]; bool enable = READ_ONCE(insn->current_mode) == INSN_HW; + if (insn->status == INSN_UNAVAILABLE) + continue; + if (insn->set_hw_mode && insn->set_hw_mode(enable)) { pr_warn("CPU[%u] cannot support the emulation of %s", cpu, insn->name); --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/fpsimd.c +++ linux-xilinx-6.8.0/arch/arm64/kernel/fpsimd.c @@ -1518,6 +1518,27 @@ task->thread.kernel_fpsimd_cpu = smp_processor_id(); } +/* + * Invalidate any task's FPSIMD state that is present on this cpu. + * The FPSIMD context should be acquired with get_cpu_fpsimd_context() + * before calling this function. + */ +static void fpsimd_flush_cpu_state(void) +{ + WARN_ON(!system_supports_fpsimd()); + __this_cpu_write(fpsimd_last_state.st, NULL); + + /* + * Leaving streaming mode enabled will cause issues for any kernel + * NEON and leaving streaming mode or ZA enabled may increase power + * consumption. + */ + if (system_supports_sme()) + sme_smstop(); + + set_thread_flag(TIF_FOREIGN_FPSTATE); +} + void fpsimd_thread_switch(struct task_struct *next) { bool wrong_task, wrong_cpu; @@ -1535,7 +1556,7 @@ if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) { fpsimd_load_kernel_state(next); - set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); + fpsimd_flush_cpu_state(); } else { /* * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's @@ -1825,27 +1846,6 @@ } /* - * Invalidate any task's FPSIMD state that is present on this cpu. - * The FPSIMD context should be acquired with get_cpu_fpsimd_context() - * before calling this function. - */ -static void fpsimd_flush_cpu_state(void) -{ - WARN_ON(!system_supports_fpsimd()); - __this_cpu_write(fpsimd_last_state.st, NULL); - - /* - * Leaving streaming mode enabled will cause issues for any kernel - * NEON and leaving streaming mode or ZA enabled may increase power - * consumption. - */ - if (system_supports_sme()) - sme_smstop(); - - set_thread_flag(TIF_FOREIGN_FPSTATE); -} - -/* * Save the FPSIMD state to memory and invalidate cpu view. * This function must be called with preemption disabled. */ @@ -1923,7 +1923,7 @@ put_cpu_fpsimd_context(); } -EXPORT_SYMBOL_GPL(kernel_neon_begin); +EXPORT_SYMBOL(kernel_neon_begin); /* * kernel_neon_end(): give the CPU FPSIMD registers back to the current task @@ -1950,7 +1950,7 @@ else clear_thread_flag(TIF_KERNEL_FPSTATE); } -EXPORT_SYMBOL_GPL(kernel_neon_end); +EXPORT_SYMBOL(kernel_neon_end); #ifdef CONFIG_EFI --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/head.S +++ linux-xilinx-6.8.0/arch/arm64/kernel/head.S @@ -569,6 +569,11 @@ adr_l x1, __hyp_text_end adr_l x2, dcache_clean_poc blr x2 + + mov_q x0, INIT_SCTLR_EL2_MMU_OFF + pre_disable_mmu_workaround + msr sctlr_el2, x0 + isb 0: mov_q x0, HCR_HOST_NVHE_FLAGS msr hcr_el2, x0 --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/idreg-override.c +++ linux-xilinx-6.8.0/arch/arm64/kernel/idreg-override.c @@ -308,7 +308,8 @@ match_options(buf); for (i = 0; parse_aliases && i < ARRAY_SIZE(aliases); i++) - if (!memcmp(buf, aliases[i].alias, len + 1)) + if (len == strlen(aliases[i].alias) && + !memcmp(buf, aliases[i].alias, len + 1)) __parse_cmdline(aliases[i].feature, false); } while (1); } --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/irq.c +++ linux-xilinx-6.8.0/arch/arm64/kernel/irq.c @@ -100,7 +100,11 @@ void (*handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq; void (*handle_arch_fiq)(struct pt_regs *) __ro_after_init = default_handle_fiq; +#ifndef CONFIG_IRQCHIP_XILINX_INTC_MODULE_SUPPORT_EXPERIMENTAL int __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) +#else +int set_handle_irq(void (*handle_irq)(struct pt_regs *)) +#endif { if (handle_arch_irq != default_handle_irq) return -EBUSY; --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/ptrace.c +++ linux-xilinx-6.8.0/arch/arm64/kernel/ptrace.c @@ -729,7 +729,6 @@ { unsigned int vq; bool active; - bool fpsimd_only; enum vec_type task_type; memset(header, 0, sizeof(*header)); @@ -745,12 +744,10 @@ case ARM64_VEC_SVE: if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT)) header->flags |= SVE_PT_VL_INHERIT; - fpsimd_only = !test_tsk_thread_flag(target, TIF_SVE); break; case ARM64_VEC_SME: if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT)) header->flags |= SVE_PT_VL_INHERIT; - fpsimd_only = false; break; default: WARN_ON_ONCE(1); @@ -758,7 +755,7 @@ } if (active) { - if (fpsimd_only) { + if (target->thread.fp_type == FP_STATE_FPSIMD) { header->flags |= SVE_PT_REGS_FPSIMD; } else { header->flags |= SVE_PT_REGS_SVE; --- linux-xilinx-6.8.0.orig/arch/arm64/kernel/syscall.c +++ linux-xilinx-6.8.0/arch/arm64/kernel/syscall.c @@ -56,17 +56,15 @@ syscall_set_return_value(current, regs, 0, ret); /* - * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), - * but not enough for arm64 stack utilization comfort. To keep - * reasonable stack head room, reduce the maximum offset to 9 bits. + * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 + * bits. The actual entropy will be further reduced by the compiler + * when applying stack alignment constraints: the AAPCS mandates a + * 16-byte aligned SP at function boundaries, which will remove the + * 4 low bits from any entropy chosen here. * - * The actual entropy will be further reduced by the compiler when - * applying stack alignment constraints: the AAPCS mandates a - * 16-byte (i.e. 4-bit) aligned SP at function boundaries. - * - * The resulting 5 bits of entropy is seen in SP[8:4]. + * The resulting 6 bits of entropy is seen in SP[9:4]. */ - choose_random_kstack_offset(get_random_u16() & 0x1FF); + choose_random_kstack_offset(get_random_u16()); } static inline bool has_syscall_work(unsigned long flags) --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/arm.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/arm.c @@ -191,6 +191,23 @@ } +static void kvm_destroy_mpidr_data(struct kvm *kvm) +{ + struct kvm_mpidr_data *data; + + mutex_lock(&kvm->arch.config_lock); + + data = rcu_dereference_protected(kvm->arch.mpidr_data, + lockdep_is_held(&kvm->arch.config_lock)); + if (data) { + rcu_assign_pointer(kvm->arch.mpidr_data, NULL); + synchronize_rcu(); + kfree(data); + } + + mutex_unlock(&kvm->arch.config_lock); +} + /** * kvm_arch_destroy_vm - destroy the VM data structure * @kvm: pointer to the KVM struct @@ -205,7 +222,8 @@ if (is_protected_kvm_enabled()) pkvm_destroy_hyp_vm(kvm); - kfree(kvm->arch.mpidr_data); + kvm_destroy_mpidr_data(kvm); + kvm_destroy_vcpus(kvm); kvm_unshare_hyp(kvm, kvm + 1); @@ -390,6 +408,13 @@ vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; + /* + * This vCPU may have been created after mpidr_data was initialized. + * Throw out the pre-computed mappings if that is the case which forces + * KVM to fall back to iteratively searching the vCPUs. + */ + kvm_destroy_mpidr_data(vcpu->kvm); + err = kvm_vgic_vcpu_init(vcpu); if (err) return err; @@ -589,7 +614,8 @@ mutex_lock(&kvm->arch.config_lock); - if (kvm->arch.mpidr_data || atomic_read(&kvm->online_vcpus) == 1) + if (rcu_access_pointer(kvm->arch.mpidr_data) || + atomic_read(&kvm->online_vcpus) == 1) goto out; kvm_for_each_vcpu(c, vcpu, kvm) { @@ -626,7 +652,7 @@ data->cmpidr_to_idx[index] = c; } - kvm->arch.mpidr_data = data; + rcu_assign_pointer(kvm->arch.mpidr_data, data); out: mutex_unlock(&kvm->arch.config_lock); } @@ -2459,21 +2485,27 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr) { - struct kvm_vcpu *vcpu; + struct kvm_vcpu *vcpu = NULL; + struct kvm_mpidr_data *data; unsigned long i; mpidr &= MPIDR_HWID_BITMASK; - if (kvm->arch.mpidr_data) { - u16 idx = kvm_mpidr_index(kvm->arch.mpidr_data, mpidr); + rcu_read_lock(); + data = rcu_dereference(kvm->arch.mpidr_data); - vcpu = kvm_get_vcpu(kvm, - kvm->arch.mpidr_data->cmpidr_to_idx[idx]); + if (data) { + u16 idx = kvm_mpidr_index(data, mpidr); + + vcpu = kvm_get_vcpu(kvm, data->cmpidr_to_idx[idx]); if (mpidr != kvm_vcpu_get_mpidr_aff(vcpu)) vcpu = NULL; + } + rcu_read_unlock(); + + if (vcpu) return vcpu; - } kvm_for_each_vcpu(i, vcpu, kvm) { if (mpidr == kvm_vcpu_get_mpidr_aff(vcpu)) --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/guest.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/guest.c @@ -251,6 +251,7 @@ case PSR_AA32_MODE_SVC: case PSR_AA32_MODE_ABT: case PSR_AA32_MODE_UND: + case PSR_AA32_MODE_SYS: if (!vcpu_el1_is_32bit(vcpu)) return -EINVAL; break; @@ -276,7 +277,7 @@ if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) { int i, nr_reg; - switch (*vcpu_cpsr(vcpu)) { + switch (*vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK) { /* * Either we are dealing with user mode, and only the * first 15 registers (+ PC) must be narrowed to 32bit. --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/hyp/aarch32.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/hyp/aarch32.c @@ -50,9 +50,23 @@ u32 cpsr_cond; int cond; - /* Top two bits non-zero? Unconditional. */ - if (kvm_vcpu_get_esr(vcpu) >> 30) + /* + * These are the exception classes that could fire with a + * conditional instruction. + */ + switch (kvm_vcpu_trap_get_class(vcpu)) { + case ESR_ELx_EC_CP15_32: + case ESR_ELx_EC_CP15_64: + case ESR_ELx_EC_CP14_MR: + case ESR_ELx_EC_CP14_LS: + case ESR_ELx_EC_FP_ASIMD: + case ESR_ELx_EC_CP10_ID: + case ESR_ELx_EC_CP14_64: + case ESR_ELx_EC_SVC32: + break; + default: return true; + } /* Is condition field valid? */ cond = kvm_vcpu_get_condition(vcpu); --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/hyp/nvhe/tlb.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/hyp/nvhe/tlb.c @@ -154,7 +154,8 @@ /* Switch to requested VMID */ __tlb_switch_to_guest(mmu, &cxt, false); - __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0); + __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, + TLBI_TTL_UNKNOWN); dsb(ish); __tlbi(vmalle1is); --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/hyp/pgtable.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/hyp/pgtable.c @@ -829,12 +829,15 @@ * Perform the appropriate TLB invalidation based on the * evicted pte value (if any). */ - if (kvm_pte_table(ctx->old, ctx->level)) - kvm_tlb_flush_vmid_range(mmu, ctx->addr, - kvm_granule_size(ctx->level)); - else if (kvm_pte_valid(ctx->old)) + if (kvm_pte_table(ctx->old, ctx->level)) { + u64 size = kvm_granule_size(ctx->level); + u64 addr = ALIGN_DOWN(ctx->addr, size); + + kvm_tlb_flush_vmid_range(mmu, addr, size); + } else if (kvm_pte_valid(ctx->old)) { kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr, ctx->level); + } } if (stage2_pte_is_counted(ctx->old)) --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/hyp/vhe/tlb.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/hyp/vhe/tlb.c @@ -171,7 +171,8 @@ /* Switch to requested VMID */ __tlb_switch_to_guest(mmu, &cxt); - __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0); + __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, + TLBI_TTL_UNKNOWN); dsb(ish); __tlbi(vmalle1is); --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/mmu.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/mmu.c @@ -1631,7 +1631,7 @@ fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); is_iabt = kvm_vcpu_trap_is_iabt(vcpu); - if (esr_fsc_is_permission_fault(esr)) { + if (esr_fsc_is_translation_fault(esr)) { /* Beyond sanitised PARange (which is the IPA limit) */ if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) { kvm_inject_size_fault(vcpu); --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/vgic/vgic-init.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/vgic/vgic-init.c @@ -355,7 +355,7 @@ if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list) - vgic_v3_free_redist_region(rdreg); + vgic_v3_free_redist_region(kvm, rdreg); INIT_LIST_HEAD(&dist->rd_regions); } else { dist->vgic_cpu_base = VGIC_ADDR_UNDEF; --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/vgic/vgic-kvm-device.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/vgic/vgic-kvm-device.c @@ -338,12 +338,12 @@ int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr, struct vgic_reg_attr *reg_attr) { - int cpuid; + int cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr); - cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr); - - reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid); reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK; + reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid); + if (!reg_attr->vcpu) + return -EINVAL; return 0; } --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ linux-xilinx-6.8.0/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -919,8 +919,19 @@ return ret; } -void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg) +void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg) { + struct kvm_vcpu *vcpu; + unsigned long c; + + lockdep_assert_held(&kvm->arch.config_lock); + + /* Garbage collect the region */ + kvm_for_each_vcpu(c, vcpu, kvm) { + if (vcpu->arch.vgic_cpu.rdreg == rdreg) + vcpu->arch.vgic_cpu.rdreg = NULL; + } + list_del(&rdreg->list); kfree(rdreg); } @@ -945,7 +956,7 @@ mutex_lock(&kvm->arch.config_lock); rdreg = vgic_v3_rdist_region_from_index(kvm, index); - vgic_v3_free_redist_region(rdreg); + vgic_v3_free_redist_region(kvm, rdreg); mutex_unlock(&kvm->arch.config_lock); return ret; } --- linux-xilinx-6.8.0.orig/arch/arm64/kvm/vgic/vgic.h +++ linux-xilinx-6.8.0/arch/arm64/kvm/vgic/vgic.h @@ -310,7 +310,7 @@ struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm, u32 index); -void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg); +void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg); bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size); --- linux-xilinx-6.8.0.orig/arch/arm64/mm/pageattr.c +++ linux-xilinx-6.8.0/arch/arm64/mm/pageattr.c @@ -219,9 +219,6 @@ pte_t *ptep; unsigned long addr = (unsigned long)page_address(page); - if (!can_set_direct_map()) - return true; - pgdp = pgd_offset_k(addr); if (pgd_none(READ_ONCE(*pgdp))) return false; --- linux-xilinx-6.8.0.orig/arch/arm64/net/bpf_jit_comp.c +++ linux-xilinx-6.8.0/arch/arm64/net/bpf_jit_comp.c @@ -876,7 +876,7 @@ emit(A64_UXTH(is64, dst, dst), ctx); break; case 32: - emit(A64_REV32(is64, dst, dst), ctx); + emit(A64_REV32(0, dst, dst), ctx); /* upper 32 bits already cleared */ break; case 64: @@ -1189,7 +1189,7 @@ } else { emit_a64_mov_i(1, tmp, off, ctx); if (sign_extend) - emit(A64_LDRSW(dst, src_adj, off_adj), ctx); + emit(A64_LDRSW(dst, src, tmp), ctx); else emit(A64_LDR32(dst, src, tmp), ctx); } @@ -1648,7 +1648,8 @@ prog->jited_len = 0; goto out_off; } - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) + goto out_off; } else { jit_data->ctx = ctx; jit_data->image = image_ptr; @@ -1738,15 +1739,15 @@ emit_call(enter_prog, ctx); + /* save return value to callee saved register x20 */ + emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx); + /* if (__bpf_prog_enter(prog) == 0) * goto skip_exec_of_prog; */ branch = ctx->image + ctx->idx; emit(A64_NOP, ctx); - /* save return value to callee saved register x20 */ - emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx); - emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx); if (!p->jited) emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx); --- linux-xilinx-6.8.0.orig/arch/csky/include/uapi/asm/unistd.h +++ linux-xilinx-6.8.0/arch/csky/include/uapi/asm/unistd.h @@ -6,6 +6,7 @@ #define __ARCH_WANT_SYS_CLONE3 #define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_TIME32_SYSCALLS +#define __ARCH_WANT_SYNC_FILE_RANGE2 #include #define __NR_set_thread_area (__NR_arch_specific_syscall + 0) --- linux-xilinx-6.8.0.orig/arch/csky/kernel/probes/ftrace.c +++ linux-xilinx-6.8.0/arch/csky/kernel/probes/ftrace.c @@ -12,6 +12,9 @@ struct kprobe_ctlblk *kcb; struct pt_regs *regs; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/hexagon/include/asm/syscalls.h +++ linux-xilinx-6.8.0/arch/hexagon/include/asm/syscalls.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice, + u32 a2, u32 a3, u32 a4, u32 a5); --- linux-xilinx-6.8.0.orig/arch/hexagon/include/uapi/asm/unistd.h +++ linux-xilinx-6.8.0/arch/hexagon/include/uapi/asm/unistd.h @@ -36,5 +36,6 @@ #define __ARCH_WANT_SYS_VFORK #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_TIME32_SYSCALLS +#define __ARCH_WANT_SYNC_FILE_RANGE2 #include --- linux-xilinx-6.8.0.orig/arch/hexagon/kernel/syscalltab.c +++ linux-xilinx-6.8.0/arch/hexagon/kernel/syscalltab.c @@ -14,6 +14,13 @@ #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), +SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice, + SC_ARG64(offset), SC_ARG64(len)) +{ + return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice); +} +#define sys_fadvise64_64 sys_hexagon_fadvise64_64 + void *sys_call_table[__NR_syscalls] = { #include }; --- linux-xilinx-6.8.0.orig/arch/hexagon/kernel/vmlinux.lds.S +++ linux-xilinx-6.8.0/arch/hexagon/kernel/vmlinux.lds.S @@ -63,6 +63,7 @@ STABS_DEBUG DWARF_DEBUG ELF_DETAILS + .hexagon.attributes 0 : { *(.hexagon.attributes) } DISCARDS } --- linux-xilinx-6.8.0.orig/arch/loongarch/boot/dts/loongson-2k0500-ref.dts +++ linux-xilinx-6.8.0/arch/loongarch/boot/dts/loongson-2k0500-ref.dts @@ -44,14 +44,14 @@ &gmac0 { status = "okay"; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; bus_id = <0x0>; }; &gmac1 { status = "okay"; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; bus_id = <0x1>; }; --- linux-xilinx-6.8.0.orig/arch/loongarch/boot/dts/loongson-2k1000-ref.dts +++ linux-xilinx-6.8.0/arch/loongarch/boot/dts/loongson-2k1000-ref.dts @@ -43,7 +43,7 @@ &gmac0 { status = "okay"; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&phy0>; mdio { compatible = "snps,dwmac-mdio"; @@ -58,7 +58,7 @@ &gmac1 { status = "okay"; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&phy1>; mdio { compatible = "snps,dwmac-mdio"; --- linux-xilinx-6.8.0.orig/arch/loongarch/crypto/crc32-loongarch.c +++ linux-xilinx-6.8.0/arch/loongarch/crypto/crc32-loongarch.c @@ -44,7 +44,6 @@ CRC32(crc, value, w); p += sizeof(u32); - len -= sizeof(u32); } if (len & sizeof(u16)) { @@ -80,7 +79,6 @@ CRC32C(crc, value, w); p += sizeof(u32); - len -= sizeof(u32); } if (len & sizeof(u16)) { --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/Kbuild +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/Kbuild @@ -4,6 +4,7 @@ generic-y += parport.h generic-y += early_ioremap.h generic-y += qrwlock.h +generic-y += qspinlock.h generic-y += rwsem.h generic-y += segment.h generic-y += user.h --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/hw_breakpoint.h +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/hw_breakpoint.h @@ -75,6 +75,8 @@ #define CSR_MWPC_NUM 0x3f #define CTRL_PLV_ENABLE 0x1e +#define CTRL_PLV0_ENABLE 0x02 +#define CTRL_PLV3_ENABLE 0x10 #define MWPnCFG3_LoadEn 8 #define MWPnCFG3_StoreEn 9 @@ -101,7 +103,7 @@ struct perf_event_attr; extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, - int *gen_len, int *gen_type, int *offset); + int *gen_len, int *gen_type); extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); extern int hw_breakpoint_arch_parse(struct perf_event *bp, const struct perf_event_attr *attr, --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/io.h +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/io.h @@ -71,6 +71,8 @@ #define memcpy_fromio(a, c, l) __memcpy_fromio((a), (c), (l)) #define memcpy_toio(c, a, l) __memcpy_toio((c), (a), (l)) +#define __io_aw() mmiowb() + #include #define ARCH_HAS_VALID_PHYS_ADDR_RANGE --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/numa.h +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/numa.h @@ -56,6 +56,7 @@ static inline void early_numa_add_cpu(int cpuid, s16 node) { } static inline void numa_add_cpu(unsigned int cpu) { } static inline void numa_remove_cpu(unsigned int cpu) { } +static inline void set_cpuid_to_node(int cpuid, s16 node) { } static inline int early_cpu_to_node(int cpu) { --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/percpu.h +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/percpu.h @@ -29,7 +29,12 @@ __my_cpu_offset = off; csr_write64(off, PERCPU_BASE_KS); } -#define __my_cpu_offset __my_cpu_offset + +#define __my_cpu_offset \ +({ \ + __asm__ __volatile__("":"+r"(__my_cpu_offset)); \ + __my_cpu_offset; \ +}) #define PERCPU_OP(op, asm_op, c_op) \ static __always_inline unsigned long __percpu_##op(void *ptr, \ --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/perf_event.h +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/perf_event.h @@ -7,6 +7,13 @@ #ifndef __LOONGARCH_PERF_EVENT_H__ #define __LOONGARCH_PERF_EVENT_H__ +#include + #define perf_arch_bpf_user_pt_regs(regs) (struct user_pt_regs *)regs +#define perf_arch_fetch_caller_regs(regs, __ip) { \ + (regs)->csr_era = (__ip); \ + (regs)->regs[3] = (unsigned long) __builtin_frame_address(0); \ +} + #endif /* __LOONGARCH_PERF_EVENT_H__ */ --- linux-xilinx-6.8.0.orig/arch/loongarch/include/asm/stackframe.h +++ linux-xilinx-6.8.0/arch/loongarch/include/asm/stackframe.h @@ -41,7 +41,7 @@ .macro JUMP_VIRT_ADDR temp1 temp2 li.d \temp1, CACHE_BASE pcaddi \temp2, 0 - or \temp1, \temp1, \temp2 + bstrins.d \temp1, \temp2, (DMW_PABITS - 1), 0 jirl zero, \temp1, 0xc .endm --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/ftrace_dyn.c +++ linux-xilinx-6.8.0/arch/loongarch/kernel/ftrace_dyn.c @@ -287,6 +287,9 @@ struct kprobe *p; struct kprobe_ctlblk *kcb; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/head.S +++ linux-xilinx-6.8.0/arch/loongarch/kernel/head.S @@ -22,7 +22,7 @@ _head: .word MZ_MAGIC /* "MZ", MS-DOS header */ .org 0x8 - .dword kernel_entry /* Kernel entry point */ + .dword _kernel_entry /* Kernel entry point (physical address) */ .dword _kernel_asize /* Kernel image effective size */ .quad PHYS_LINK_KADDR /* Kernel image load offset from start of RAM */ .org 0x38 /* 0x20 ~ 0x37 reserved */ --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/hw_breakpoint.c +++ linux-xilinx-6.8.0/arch/loongarch/kernel/hw_breakpoint.c @@ -174,11 +174,21 @@ static int hw_breakpoint_control(struct perf_event *bp, enum hw_breakpoint_ops ops) { - u32 ctrl; + u32 ctrl, privilege; int i, max_slots, enable; + struct pt_regs *regs; struct perf_event **slots; struct arch_hw_breakpoint *info = counter_arch_bp(bp); + if (arch_check_bp_in_kernelspace(info)) + privilege = CTRL_PLV0_ENABLE; + else + privilege = CTRL_PLV3_ENABLE; + + /* Whether bp belongs to a task. */ + if (bp->hw.target) + regs = task_pt_regs(bp->hw.target); + if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { /* Breakpoint */ slots = this_cpu_ptr(bp_on_reg); @@ -197,31 +207,38 @@ switch (ops) { case HW_BREAKPOINT_INSTALL: /* Set the FWPnCFG/MWPnCFG 1~4 register. */ - write_wb_reg(CSR_CFG_ADDR, i, 0, info->address); - write_wb_reg(CSR_CFG_ADDR, i, 1, info->address); - write_wb_reg(CSR_CFG_MASK, i, 0, info->mask); - write_wb_reg(CSR_CFG_MASK, i, 1, info->mask); - write_wb_reg(CSR_CFG_ASID, i, 0, 0); - write_wb_reg(CSR_CFG_ASID, i, 1, 0); if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { - write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE); + write_wb_reg(CSR_CFG_ADDR, i, 0, info->address); + write_wb_reg(CSR_CFG_MASK, i, 0, info->mask); + write_wb_reg(CSR_CFG_ASID, i, 0, 0); + write_wb_reg(CSR_CFG_CTRL, i, 0, privilege); } else { + write_wb_reg(CSR_CFG_ADDR, i, 1, info->address); + write_wb_reg(CSR_CFG_MASK, i, 1, info->mask); + write_wb_reg(CSR_CFG_ASID, i, 1, 0); ctrl = encode_ctrl_reg(info->ctrl); - write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | CTRL_PLV_ENABLE); + write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | privilege); } enable = csr_read64(LOONGARCH_CSR_CRMD); csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD); + if (bp->hw.target) + regs->csr_prmd |= CSR_PRMD_PWE; break; case HW_BREAKPOINT_UNINSTALL: /* Reset the FWPnCFG/MWPnCFG 1~4 register. */ - write_wb_reg(CSR_CFG_ADDR, i, 0, 0); - write_wb_reg(CSR_CFG_ADDR, i, 1, 0); - write_wb_reg(CSR_CFG_MASK, i, 0, 0); - write_wb_reg(CSR_CFG_MASK, i, 1, 0); - write_wb_reg(CSR_CFG_CTRL, i, 0, 0); - write_wb_reg(CSR_CFG_CTRL, i, 1, 0); - write_wb_reg(CSR_CFG_ASID, i, 0, 0); - write_wb_reg(CSR_CFG_ASID, i, 1, 0); + if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { + write_wb_reg(CSR_CFG_ADDR, i, 0, 0); + write_wb_reg(CSR_CFG_MASK, i, 0, 0); + write_wb_reg(CSR_CFG_CTRL, i, 0, 0); + write_wb_reg(CSR_CFG_ASID, i, 0, 0); + } else { + write_wb_reg(CSR_CFG_ADDR, i, 1, 0); + write_wb_reg(CSR_CFG_MASK, i, 1, 0); + write_wb_reg(CSR_CFG_CTRL, i, 1, 0); + write_wb_reg(CSR_CFG_ASID, i, 1, 0); + } + if (bp->hw.target) + regs->csr_prmd &= ~CSR_PRMD_PWE; break; } @@ -283,7 +300,7 @@ * to generic breakpoint descriptions. */ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, - int *gen_len, int *gen_type, int *offset) + int *gen_len, int *gen_type) { /* Type */ switch (ctrl.type) { @@ -303,11 +320,6 @@ return -EINVAL; } - if (!ctrl.len) - return -EINVAL; - - *offset = __ffs(ctrl.len); - /* Len */ switch (ctrl.len) { case LOONGARCH_BREAKPOINT_LEN_1: @@ -386,21 +398,17 @@ struct arch_hw_breakpoint *hw) { int ret; - u64 alignment_mask, offset; + u64 alignment_mask; /* Build the arch_hw_breakpoint. */ ret = arch_build_bp_info(bp, attr, hw); if (ret) return ret; - if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE) - alignment_mask = 0x7; - else + if (hw->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) { alignment_mask = 0x3; - offset = hw->address & alignment_mask; - - hw->address &= ~alignment_mask; - hw->ctrl.len <<= offset; + hw->address &= ~alignment_mask; + } return 0; } @@ -471,12 +479,15 @@ slots = this_cpu_ptr(bp_on_reg); for (i = 0; i < boot_cpu_data.watch_ireg_count; ++i) { - bp = slots[i]; - if (bp == NULL) - continue; - perf_bp_event(bp, regs); + if ((csr_read32(LOONGARCH_CSR_FWPS) & (0x1 << i))) { + bp = slots[i]; + if (bp == NULL) + continue; + perf_bp_event(bp, regs); + csr_write32(0x1 << i, LOONGARCH_CSR_FWPS); + update_bp_registers(regs, 0, 0); + } } - update_bp_registers(regs, 0, 0); } NOKPROBE_SYMBOL(breakpoint_handler); @@ -488,12 +499,15 @@ slots = this_cpu_ptr(wp_on_reg); for (i = 0; i < boot_cpu_data.watch_dreg_count; ++i) { - wp = slots[i]; - if (wp == NULL) - continue; - perf_bp_event(wp, regs); + if ((csr_read32(LOONGARCH_CSR_MWPS) & (0x1 << i))) { + wp = slots[i]; + if (wp == NULL) + continue; + perf_bp_event(wp, regs); + csr_write32(0x1 << i, LOONGARCH_CSR_MWPS); + update_bp_registers(regs, 0, 1); + } } - update_bp_registers(regs, 0, 1); } NOKPROBE_SYMBOL(watchpoint_handler); --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/perf_event.c +++ linux-xilinx-6.8.0/arch/loongarch/kernel/perf_event.c @@ -884,4 +884,4 @@ return 0; } -early_initcall(init_hw_perf_events); +pure_initcall(init_hw_perf_events); --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/ptrace.c +++ linux-xilinx-6.8.0/arch/loongarch/kernel/ptrace.c @@ -494,28 +494,14 @@ struct arch_hw_breakpoint_ctrl ctrl, struct perf_event_attr *attr) { - int err, len, type, offset; + int err, len, type; - err = arch_bp_generic_fields(ctrl, &len, &type, &offset); + err = arch_bp_generic_fields(ctrl, &len, &type); if (err) return err; - switch (note_type) { - case NT_LOONGARCH_HW_BREAK: - if ((type & HW_BREAKPOINT_X) != type) - return -EINVAL; - break; - case NT_LOONGARCH_HW_WATCH: - if ((type & HW_BREAKPOINT_RW) != type) - return -EINVAL; - break; - default: - return -EINVAL; - } - attr->bp_len = len; attr->bp_type = type; - attr->bp_addr += offset; return 0; } @@ -609,10 +595,27 @@ return PTR_ERR(bp); attr = bp->attr; - decode_ctrl_reg(uctrl, &ctrl); - err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); - if (err) - return err; + + switch (note_type) { + case NT_LOONGARCH_HW_BREAK: + ctrl.type = LOONGARCH_BREAKPOINT_EXECUTE; + ctrl.len = LOONGARCH_BREAKPOINT_LEN_4; + break; + case NT_LOONGARCH_HW_WATCH: + decode_ctrl_reg(uctrl, &ctrl); + break; + default: + return -EINVAL; + } + + if (uctrl & CTRL_PLV_ENABLE) { + err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr); + if (err) + return err; + attr.disabled = 0; + } else { + attr.disabled = 1; + } return modify_user_hw_breakpoint(bp, &attr); } @@ -643,6 +646,10 @@ struct perf_event *bp; struct perf_event_attr attr; + /* Kernel-space address cannot be monitored by user-space */ + if ((unsigned long)addr >= XKPRANGE) + return -EINVAL; + bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx); if (IS_ERR(bp)) return PTR_ERR(bp); --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/setup.c +++ linux-xilinx-6.8.0/arch/loongarch/kernel/setup.c @@ -281,7 +281,7 @@ return; /* Prefer to use built-in dtb, checking its legality first. */ - if (!fdt_check_header(__dtb_start)) + if (IS_ENABLED(CONFIG_BUILTIN_DTB) && !fdt_check_header(__dtb_start)) fdt_pointer = __dtb_start; else fdt_pointer = efi_fdt_pointer(); /* Fallback to firmware dtb */ --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/smp.c +++ linux-xilinx-6.8.0/arch/loongarch/kernel/smp.c @@ -262,7 +262,6 @@ if (cpuid == loongson_sysconf.boot_cpu_id) { cpu = 0; - numa_add_cpu(cpu); } else { cpu = cpumask_next_zero(-1, cpu_present_mask); } @@ -272,6 +271,9 @@ set_cpu_present(cpu, true); __cpu_number_map[cpuid] = cpu; __cpu_logical_map[cpu] = cpuid; + + early_numa_add_cpu(cpu, 0); + set_cpuid_to_node(cpuid, 0); } loongson_sysconf.nr_cpus = num_processors; @@ -456,6 +458,7 @@ set_cpu_possible(0, true); set_cpu_online(0, true); set_my_cpu_offset(per_cpu_offset(0)); + numa_add_cpu(0); rr_node = first_node(node_online_map); for_each_possible_cpu(cpu) { --- linux-xilinx-6.8.0.orig/arch/loongarch/kernel/vmlinux.lds.S +++ linux-xilinx-6.8.0/arch/loongarch/kernel/vmlinux.lds.S @@ -5,6 +5,7 @@ #define PAGE_SIZE _PAGE_SIZE #define RO_EXCEPTION_TABLE_ALIGN 4 +#define PHYSADDR_MASK 0xffffffffffff /* 48-bit */ /* * Put .bss..swapper_pg_dir as the first thing in .bss. This will @@ -139,10 +140,11 @@ #ifdef CONFIG_EFI_STUB /* header symbols */ - _kernel_asize = _end - _text; - _kernel_fsize = _edata - _text; - _kernel_vsize = _end - __initdata_begin; - _kernel_rsize = _edata - __initdata_begin; + _kernel_entry = ABSOLUTE(kernel_entry & PHYSADDR_MASK); + _kernel_asize = ABSOLUTE(_end - _text); + _kernel_fsize = ABSOLUTE(_edata - _text); + _kernel_vsize = ABSOLUTE(_end - __initdata_begin); + _kernel_rsize = ABSOLUTE(_edata - __initdata_begin); #endif .gptab.sdata : { --- linux-xilinx-6.8.0.orig/arch/loongarch/mm/fault.c +++ linux-xilinx-6.8.0/arch/loongarch/mm/fault.c @@ -202,10 +202,10 @@ if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if (!(vma->vm_flags & VM_READ) && address != exception_era(regs)) - goto bad_area; if (!(vma->vm_flags & VM_EXEC) && address == exception_era(regs)) goto bad_area; + if (!(vma->vm_flags & (VM_READ | VM_WRITE)) && address != exception_era(regs)) + goto bad_area; } /* --- linux-xilinx-6.8.0.orig/arch/loongarch/net/bpf_jit.c +++ linux-xilinx-6.8.0/arch/loongarch/net/bpf_jit.c @@ -1294,16 +1294,19 @@ flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx)); if (!prog->is_func || extra_pass) { + int err; + if (extra_pass && ctx.idx != jit_data->ctx.idx) { pr_err_once("multi-func JIT bug %d != %d\n", ctx.idx, jit_data->ctx.idx); - bpf_jit_binary_free(header); - prog->bpf_func = NULL; - prog->jited = 0; - prog->jited_len = 0; - goto out_offset; + goto out_free; + } + err = bpf_jit_binary_lock_ro(header); + if (err) { + pr_err_once("bpf_jit_binary_lock_ro() returned %d\n", + err); + goto out_free; } - bpf_jit_binary_lock_ro(header); } else { jit_data->ctx = ctx; jit_data->image = image_ptr; @@ -1334,6 +1337,13 @@ out_offset = -1; return prog; + +out_free: + bpf_jit_binary_free(header); + prog->bpf_func = NULL; + prog->jited = 0; + prog->jited_len = 0; + goto out_offset; } /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ --- linux-xilinx-6.8.0.orig/arch/m68k/kernel/entry.S +++ linux-xilinx-6.8.0/arch/m68k/kernel/entry.S @@ -430,7 +430,9 @@ movec %a0,%dfc /* restore status register */ - movew %a1@(TASK_THREAD+THREAD_SR),%sr + movew %a1@(TASK_THREAD+THREAD_SR),%d0 + oriw #0x0700,%d0 + movew %d0,%sr rts --- linux-xilinx-6.8.0.orig/arch/m68k/mac/misc.c +++ linux-xilinx-6.8.0/arch/m68k/mac/misc.c @@ -453,30 +453,18 @@ void mac_reset(void) { - if (macintosh_config->adb_type == MAC_ADB_II && - macintosh_config->ident != MAC_MODEL_SE30) { - /* need ROMBASE in booter */ - /* indeed, plus need to MAP THE ROM !! */ - - if (mac_bi_data.rombase == 0) - mac_bi_data.rombase = 0x40800000; - - /* works on some */ - rom_reset = (void *) (mac_bi_data.rombase + 0xa); - - local_irq_disable(); - rom_reset(); #ifdef CONFIG_ADB_CUDA - } else if (macintosh_config->adb_type == MAC_ADB_EGRET || - macintosh_config->adb_type == MAC_ADB_CUDA) { + if (macintosh_config->adb_type == MAC_ADB_EGRET || + macintosh_config->adb_type == MAC_ADB_CUDA) { cuda_restart(); + } else #endif #ifdef CONFIG_ADB_PMU - } else if (macintosh_config->adb_type == MAC_ADB_PB2) { + if (macintosh_config->adb_type == MAC_ADB_PB2) { pmu_restart(); + } else #endif - } else if (CPU_IS_030) { - + if (CPU_IS_030) { /* 030-specific reset routine. The idea is general, but the * specific registers to reset are '030-specific. Until I * have a non-030 machine, I can't test anything else. @@ -524,6 +512,18 @@ "jmp %/a0@\n\t" /* jump to the reset vector */ ".chip 68k" : : "r" (offset), "a" (rombase) : "a0"); + } else { + /* need ROMBASE in booter */ + /* indeed, plus need to MAP THE ROM !! */ + + if (mac_bi_data.rombase == 0) + mac_bi_data.rombase = 0x40800000; + + /* works on some */ + rom_reset = (void *)(mac_bi_data.rombase + 0xa); + + local_irq_disable(); + rom_reset(); } /* should never get here */ --- linux-xilinx-6.8.0.orig/arch/microblaze/include/asm/sections.h +++ linux-xilinx-6.8.0/arch/microblaze/include/asm/sections.h @@ -14,6 +14,9 @@ extern char _ssbss[], _esbss[]; extern unsigned long __ivt_start[], __ivt_end[]; +extern char __initramfs_end[]; +extern char _end_tlb_mapping[]; + extern u32 _fdt_start[], _fdt_end[]; # endif /* !__ASSEMBLY__ */ --- linux-xilinx-6.8.0.orig/arch/microblaze/kernel/Makefile +++ linux-xilinx-6.8.0/arch/microblaze/kernel/Makefile @@ -7,7 +7,6 @@ # Do not trace early boot code and low level code CFLAGS_REMOVE_timer.o = -pg CFLAGS_REMOVE_intc.o = -pg -CFLAGS_REMOVE_early_printk.o = -pg CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_process.o = -pg endif --- linux-xilinx-6.8.0.orig/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ linux-xilinx-6.8.0/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -18,7 +18,7 @@ static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER; #define err_printk(x) \ - early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n"); + pr_err("ERROR: Microblaze " x "-different for kernel and DTS\n"); void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) { --- linux-xilinx-6.8.0.orig/arch/microblaze/kernel/head.S +++ linux-xilinx-6.8.0/arch/microblaze/kernel/head.S @@ -173,9 +173,8 @@ tophys(r4,r3) /* Load the kernel physical address */ /* start to do TLB calculation */ - addik r12, r0, _end + addik r12, r0, _end_tlb_mapping rsub r12, r3, r12 - addik r12, r12, CONFIG_LOWMEM_SIZE >> PTE_SHIFT /* that's the pad */ or r9, r0, r0 /* TLB0 = 0 */ or r10, r0, r0 /* TLB1 = 0 */ --- linux-xilinx-6.8.0.orig/arch/microblaze/kernel/setup.c +++ linux-xilinx-6.8.0/arch/microblaze/kernel/setup.c @@ -132,7 +132,7 @@ if (fdt) pr_info("FDT at 0x%08x\n", fdt); else - pr_info("Compiled-in FDT at %p\n", _fdt_start); + pr_info("Compiled-in FDT at 0x%08x\n", (unsigned)&_fdt_start); #ifdef CONFIG_MTD_UCLINUX pr_info("Found romfs @ 0x%08x (0x%08x)\n", --- linux-xilinx-6.8.0.orig/arch/microblaze/kernel/vmlinux.lds.S +++ linux-xilinx-6.8.0/arch/microblaze/kernel/vmlinux.lds.S @@ -119,12 +119,6 @@ CON_INITCALL } - __init_end_before_initramfs = .; - - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { - INIT_RAM_FS - } - __init_end = .; .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) { @@ -137,6 +131,15 @@ } . = ALIGN(PAGE_SIZE); _end = .; + /* Add space in TLB mapping for early free pages mapping */ + . = . + 0x100000; /* CONFIG_LOWMEM_SIZE >> PTE_SHIFT + space */ + + _end_tlb_mapping = . ; + + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { + INIT_RAM_FS + } + __initramfs_end = . ; DISCARDS } --- linux-xilinx-6.8.0.orig/arch/microblaze/mm/init.c +++ linux-xilinx-6.8.0/arch/microblaze/mm/init.c @@ -192,6 +192,7 @@ asmlinkage void __init mmu_init(void) { unsigned int kstart, ksize; + phys_addr_t __maybe_unused size; if (!memblock.reserved.cnt) { pr_emerg("Error memory count\n"); @@ -233,10 +234,14 @@ #if defined(CONFIG_BLK_DEV_INITRD) /* Remove the init RAM disk from the available memory. */ if (initrd_start) { - unsigned long size; size = initrd_end - initrd_start; memblock_reserve(__virt_to_phys(initrd_start), size); } + + size = __initramfs_end - __initramfs_start; + if (size) + memblock_reserve((phys_addr_t)__virt_to_phys(__initramfs_start), + size); #endif /* CONFIG_BLK_DEV_INITRD */ /* Initialize the MMU hardware */ --- linux-xilinx-6.8.0.orig/arch/mips/Kconfig +++ linux-xilinx-6.8.0/arch/mips/Kconfig @@ -14,7 +14,7 @@ select ARCH_HAS_STRNCPY_FROM_USER select ARCH_HAS_STRNLEN_USER select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_KEEP_MEMBLOCK select ARCH_USE_BUILTIN_BSWAP --- linux-xilinx-6.8.0.orig/arch/mips/bmips/setup.c +++ linux-xilinx-6.8.0/arch/mips/bmips/setup.c @@ -110,7 +110,8 @@ * RAC flush causes kernel panics on BCM6358 when booting from TP1 * because the bootloader is not initializing it properly. */ - bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)); + bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) || + !!BMIPS_GET_CBR(); } static void bcm6368_quirks(void) --- linux-xilinx-6.8.0.orig/arch/mips/include/asm/mips-cm.h +++ linux-xilinx-6.8.0/arch/mips/include/asm/mips-cm.h @@ -33,6 +33,19 @@ */ extern phys_addr_t __mips_cm_phys_base(void); +/** + * mips_cm_l2sync_phys_base - retrieve the physical base address of the CM + * L2-sync region + * + * This function returns the physical base address of the Coherence Manager + * L2-cache only region. It provides a default implementation which reads the + * CMGCRL2OnlySyncBase register where available or returns a 4K region just + * behind the CM GCR base address. It may be overridden by platforms which + * determine this address in a different way by defining a function with the + * same prototype. + */ +extern phys_addr_t mips_cm_l2sync_phys_base(void); + /* * mips_cm_is64 - determine CM register width * --- linux-xilinx-6.8.0.orig/arch/mips/include/asm/ptrace.h +++ linux-xilinx-6.8.0/arch/mips/include/asm/ptrace.h @@ -159,7 +159,7 @@ #define exception_ip(regs) exception_ip(regs) #define profile_pc(regs) instruction_pointer(regs) -extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall); +extern asmlinkage long syscall_trace_enter(struct pt_regs *regs); extern asmlinkage void syscall_trace_leave(struct pt_regs *regs); extern void die(const char *, struct pt_regs *) __noreturn; --- linux-xilinx-6.8.0.orig/arch/mips/kernel/asm-offsets.c +++ linux-xilinx-6.8.0/arch/mips/kernel/asm-offsets.c @@ -101,6 +101,7 @@ OFFSET(TI_CPU, thread_info, cpu); OFFSET(TI_PRE_COUNT, thread_info, preempt_count); OFFSET(TI_REGS, thread_info, regs); + OFFSET(TI_SYSCALL, thread_info, syscall); DEFINE(_THREAD_SIZE, THREAD_SIZE); DEFINE(_THREAD_MASK, THREAD_MASK); DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); --- linux-xilinx-6.8.0.orig/arch/mips/kernel/mips-cm.c +++ linux-xilinx-6.8.0/arch/mips/kernel/mips-cm.c @@ -201,7 +201,7 @@ phys_addr_t mips_cm_phys_base(void) __attribute__((weak, alias("__mips_cm_phys_base"))); -static phys_addr_t __mips_cm_l2sync_phys_base(void) +phys_addr_t __weak mips_cm_l2sync_phys_base(void) { u32 base_reg; @@ -217,9 +217,6 @@ return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; } -phys_addr_t mips_cm_l2sync_phys_base(void) - __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); - static void mips_cm_probe_l2sync(void) { unsigned major_rev; --- linux-xilinx-6.8.0.orig/arch/mips/kernel/ptrace.c +++ linux-xilinx-6.8.0/arch/mips/kernel/ptrace.c @@ -1317,16 +1317,13 @@ * Notification of system call entry/exit * - triggered by current->work.syscall_trace */ -asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) +asmlinkage long syscall_trace_enter(struct pt_regs *regs) { user_exit(); - current_thread_info()->syscall = syscall; - if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (ptrace_report_syscall_entry(regs)) return -1; - syscall = current_thread_info()->syscall; } #ifdef CONFIG_SECCOMP @@ -1335,7 +1332,7 @@ struct seccomp_data sd; unsigned long args[6]; - sd.nr = syscall; + sd.nr = current_thread_info()->syscall; sd.arch = syscall_get_arch(current); syscall_get_arguments(current, regs, args); for (i = 0; i < 6; i++) @@ -1345,23 +1342,23 @@ ret = __secure_computing(&sd); if (ret == -1) return ret; - syscall = current_thread_info()->syscall; } #endif if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[2]); - audit_syscall_entry(syscall, regs->regs[4], regs->regs[5], + audit_syscall_entry(current_thread_info()->syscall, + regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); /* * Negative syscall numbers are mistaken for rejected syscalls, but * won't have had the return value set appropriately, so we do so now. */ - if (syscall < 0) + if (current_thread_info()->syscall < 0) syscall_set_return_value(current, regs, -ENOSYS, 0); - return syscall; + return current_thread_info()->syscall; } /* --- linux-xilinx-6.8.0.orig/arch/mips/kernel/scall32-o32.S +++ linux-xilinx-6.8.0/arch/mips/kernel/scall32-o32.S @@ -77,6 +77,18 @@ PTR_WD load_a7, bad_stack_a7 .previous + /* + * syscall number is in v0 unless we called syscall(__NR_###) + * where the real syscall number is in a0 + */ + subu t2, v0, __NR_O32_Linux + bnez t2, 1f /* __NR_syscall at offset 0 */ + LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number + b 2f +1: + LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number +2: + lw t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_WORK_SYSCALL_ENTRY and t0, t1 @@ -114,16 +126,7 @@ SAVE_STATIC move a0, sp - /* - * syscall number is in v0 unless we called syscall(__NR_###) - * where the real syscall number is in a0 - */ - move a1, v0 - subu t2, v0, __NR_O32_Linux - bnez t2, 1f /* __NR_syscall at offset 0 */ - lw a1, PT_R4(sp) - -1: jal syscall_trace_enter + jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-xilinx-6.8.0.orig/arch/mips/kernel/scall64-n32.S +++ linux-xilinx-6.8.0/arch/mips/kernel/scall64-n32.S @@ -44,6 +44,8 @@ sd a3, PT_R26(sp) # save a3 for syscall restarting + LONG_S v0, TI_SYSCALL($28) # Store syscall number + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -72,7 +74,6 @@ n32_syscall_trace_entry: SAVE_STATIC move a0, sp - move a1, v0 jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-xilinx-6.8.0.orig/arch/mips/kernel/scall64-n64.S +++ linux-xilinx-6.8.0/arch/mips/kernel/scall64-n64.S @@ -46,6 +46,8 @@ sd a3, PT_R26(sp) # save a3 for syscall restarting + LONG_S v0, TI_SYSCALL($28) # Store syscall number + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -82,7 +84,6 @@ syscall_trace_entry: SAVE_STATIC move a0, sp - move a1, v0 jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-xilinx-6.8.0.orig/arch/mips/kernel/scall64-o32.S +++ linux-xilinx-6.8.0/arch/mips/kernel/scall64-o32.S @@ -79,6 +79,22 @@ PTR_WD load_a7, bad_stack_a7 .previous + /* + * absolute syscall number is in v0 unless we called syscall(__NR_###) + * where the real syscall number is in a0 + * note: NR_syscall is the first O32 syscall but the macro is + * only defined when compiling with -mabi=32 (CONFIG_32BIT) + * therefore __NR_O32_Linux is used (4000) + */ + + subu t2, v0, __NR_O32_Linux + bnez t2, 1f /* __NR_syscall at offset 0 */ + LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number + b 2f +1: + LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number +2: + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -113,22 +129,7 @@ sd a7, PT_R11(sp) # For indirect syscalls move a0, sp - /* - * absolute syscall number is in v0 unless we called syscall(__NR_###) - * where the real syscall number is in a0 - * note: NR_syscall is the first O32 syscall but the macro is - * only defined when compiling with -mabi=32 (CONFIG_32BIT) - * therefore __NR_O32_Linux is used (4000) - */ - .set push - .set reorder - subu t1, v0, __NR_O32_Linux - move a1, v0 - bnez t1, 1f /* __NR_syscall at offset 0 */ - ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */ - .set pop - -1: jal syscall_trace_enter + jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-xilinx-6.8.0.orig/arch/mips/kernel/syscalls/syscall_n32.tbl +++ linux-xilinx-6.8.0/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -354,7 +354,7 @@ 412 n32 utimensat_time64 sys_utimensat 413 n32 pselect6_time64 compat_sys_pselect6_time64 414 n32 ppoll_time64 compat_sys_ppoll_time64 -416 n32 io_pgetevents_time64 sys_io_pgetevents +416 n32 io_pgetevents_time64 compat_sys_io_pgetevents_time64 417 n32 recvmmsg_time64 compat_sys_recvmmsg_time64 418 n32 mq_timedsend_time64 sys_mq_timedsend 419 n32 mq_timedreceive_time64 sys_mq_timedreceive --- linux-xilinx-6.8.0.orig/arch/mips/kernel/syscalls/syscall_o32.tbl +++ linux-xilinx-6.8.0/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -27,7 +27,7 @@ 17 o32 break sys_ni_syscall # 18 was sys_stat 18 o32 unused18 sys_ni_syscall -19 o32 lseek sys_lseek +19 o32 lseek sys_lseek compat_sys_lseek 20 o32 getpid sys_getpid 21 o32 mount sys_mount 22 o32 umount sys_oldumount @@ -403,7 +403,7 @@ 412 o32 utimensat_time64 sys_utimensat sys_utimensat 413 o32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 414 o32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 -416 o32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents +416 o32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 417 o32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 418 o32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend 419 o32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive --- linux-xilinx-6.8.0.orig/arch/mips/net/bpf_jit_comp.c +++ linux-xilinx-6.8.0/arch/mips/net/bpf_jit_comp.c @@ -1012,7 +1012,8 @@ bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]); /* Set as read-only exec and flush instruction cache */ - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) + goto out_err; flush_icache_range((unsigned long)header, (unsigned long)&ctx.target[ctx.jit_index]); --- linux-xilinx-6.8.0.orig/arch/mips/pci/ops-rc32434.c +++ linux-xilinx-6.8.0/arch/mips/pci/ops-rc32434.c @@ -112,8 +112,8 @@ * gives them time to settle */ if (where == PCI_VENDOR_ID) { - if (ret == 0xffffffff || ret == 0x00000000 || - ret == 0x0000ffff || ret == 0xffff0000) { + if (*val == 0xffffffff || *val == 0x00000000 || + *val == 0x0000ffff || *val == 0xffff0000) { if (delay > 4) return 0; delay *= 2; --- linux-xilinx-6.8.0.orig/arch/mips/pci/pcie-octeon.c +++ linux-xilinx-6.8.0/arch/mips/pci/pcie-octeon.c @@ -230,12 +230,18 @@ { union cvmx_pcie_address pcie_addr; union cvmx_pciercx_cfg006 pciercx_cfg006; + union cvmx_pciercx_cfg032 pciercx_cfg032; pciercx_cfg006.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port)); if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0)) return 0; + pciercx_cfg032.u32 = + cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port)); + if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1)) + return 0; + pcie_addr.u64 = 0; pcie_addr.config.upper = 2; pcie_addr.config.io = 1; --- linux-xilinx-6.8.0.orig/arch/openrisc/kernel/traps.c +++ linux-xilinx-6.8.0/arch/openrisc/kernel/traps.c @@ -180,29 +180,39 @@ asmlinkage void do_fpe_trap(struct pt_regs *regs, unsigned long address) { - int code = FPE_FLTUNK; - unsigned long fpcsr = regs->fpcsr; - - if (fpcsr & SPR_FPCSR_IVF) - code = FPE_FLTINV; - else if (fpcsr & SPR_FPCSR_OVF) - code = FPE_FLTOVF; - else if (fpcsr & SPR_FPCSR_UNF) - code = FPE_FLTUND; - else if (fpcsr & SPR_FPCSR_DZF) - code = FPE_FLTDIV; - else if (fpcsr & SPR_FPCSR_IXF) - code = FPE_FLTRES; - - /* Clear all flags */ - regs->fpcsr &= ~SPR_FPCSR_ALLF; - - force_sig_fault(SIGFPE, code, (void __user *)regs->pc); + if (user_mode(regs)) { + int code = FPE_FLTUNK; + unsigned long fpcsr = regs->fpcsr; + + if (fpcsr & SPR_FPCSR_IVF) + code = FPE_FLTINV; + else if (fpcsr & SPR_FPCSR_OVF) + code = FPE_FLTOVF; + else if (fpcsr & SPR_FPCSR_UNF) + code = FPE_FLTUND; + else if (fpcsr & SPR_FPCSR_DZF) + code = FPE_FLTDIV; + else if (fpcsr & SPR_FPCSR_IXF) + code = FPE_FLTRES; + + /* Clear all flags */ + regs->fpcsr &= ~SPR_FPCSR_ALLF; + + force_sig_fault(SIGFPE, code, (void __user *)regs->pc); + } else { + pr_emerg("KERNEL: Illegal fpe exception 0x%.8lx\n", regs->pc); + die("Die:", regs, SIGFPE); + } } asmlinkage void do_trap(struct pt_regs *regs, unsigned long address) { - force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc); + if (user_mode(regs)) { + force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc); + } else { + pr_emerg("KERNEL: Illegal trap exception 0x%.8lx\n", regs->pc); + die("Die:", regs, SIGILL); + } } asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address) --- linux-xilinx-6.8.0.orig/arch/parisc/Kconfig +++ linux-xilinx-6.8.0/arch/parisc/Kconfig @@ -12,9 +12,10 @@ select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_MODULE_RWX - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_HAS_PTE_SPECIAL select ARCH_NO_SG_CHAIN + select ARCH_SPLIT_ARG64 if !64BIT select ARCH_SUPPORTS_HUGETLBFS if PA20 select ARCH_SUPPORTS_MEMORY_FAILURE select ARCH_STACKWALK --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/assembly.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/assembly.h @@ -97,26 +97,28 @@ * version takes two arguments: a src and destination register. * However, the source and destination registers can not be * the same register. + * + * We use add,l to avoid clobbering the C/B bits in the PSW. */ .macro tophys grvirt, grphys - ldil L%(__PAGE_OFFSET), \grphys - sub \grvirt, \grphys, \grphys + ldil L%(-__PAGE_OFFSET), \grphys + addl \grvirt, \grphys, \grphys .endm - + .macro tovirt grphys, grvirt ldil L%(__PAGE_OFFSET), \grvirt - add \grphys, \grvirt, \grvirt + addl \grphys, \grvirt, \grvirt .endm .macro tophys_r1 gr - ldil L%(__PAGE_OFFSET), %r1 - sub \gr, %r1, \gr + ldil L%(-__PAGE_OFFSET), %r1 + addl \gr, %r1, \gr .endm - + .macro tovirt_r1 gr ldil L%(__PAGE_OFFSET), %r1 - add \gr, %r1, \gr + addl \gr, %r1, \gr .endm .macro delay value --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/cacheflush.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/cacheflush.h @@ -31,18 +31,17 @@ void flush_cache_all(void); void flush_cache_mm(struct mm_struct *mm); -void flush_kernel_dcache_page_addr(const void *addr); - #define flush_kernel_dcache_range(start,size) \ flush_kernel_dcache_range_asm((start), (start)+(size)); +/* The only way to flush a vmap range is to flush whole cache */ #define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1 void flush_kernel_vmap_range(void *vaddr, int size); void invalidate_kernel_vmap_range(void *vaddr, int size); -#define flush_cache_vmap(start, end) flush_cache_all() +void flush_cache_vmap(unsigned long start, unsigned long end); #define flush_cache_vmap_early(start, end) do { } while (0) -#define flush_cache_vunmap(start, end) flush_cache_all() +void flush_cache_vunmap(unsigned long start, unsigned long end); void flush_dcache_folio(struct folio *folio); #define flush_dcache_folio flush_dcache_folio @@ -77,17 +76,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); -/* defined in pacache.S exported in cache.c used by flush_anon_page */ -void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); - #define ARCH_HAS_FLUSH_ANON_PAGE void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr); #define ARCH_HAS_FLUSH_ON_KUNMAP -static inline void kunmap_flush_on_unmap(const void *addr) -{ - flush_kernel_dcache_page_addr(addr); -} +void kunmap_flush_on_unmap(const void *addr); #endif /* _PARISC_CACHEFLUSH_H */ --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/checksum.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/checksum.h @@ -40,7 +40,7 @@ " addc %0, %5, %0\n" " addc %0, %3, %0\n" "1: ldws,ma 4(%1), %3\n" -" addib,< 0, %2, 1b\n" +" addib,> -1, %2, 1b\n" " addc %0, %3, %0\n" "\n" " extru %0, 31, 16, %4\n" @@ -126,6 +126,7 @@ ** Try to keep 4 registers with "live" values ahead of the ALU. */ +" depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */ " ldd,ma 8(%1), %4\n" /* get 1st saddr word */ " ldd,ma 8(%2), %5\n" /* get 1st daddr word */ " add %4, %0, %0\n" @@ -137,8 +138,8 @@ " add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */ " extrd,u %0, 31, 32, %4\n"/* copy upper half down */ " depdi 0, 31, 32, %0\n"/* clear upper half */ -" add %4, %0, %0\n" /* fold into 32-bits */ -" addc 0, %0, %0\n" /* add carry */ +" add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */ +" addc 0, %0, %0\n" /* add final carry */ #else @@ -163,7 +164,8 @@ " ldw,ma 4(%2), %7\n" /* 4th daddr */ " addc %6, %0, %0\n" " addc %7, %0, %0\n" -" addc %3, %0, %0\n" /* fold in proto+len, catch carry */ +" addc %3, %0, %0\n" /* fold in proto+len */ +" addc 0, %0, %0\n" /* add carry */ #endif : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len), --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/mman.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/mman.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_MMAN_H__ +#define __ASM_MMAN_H__ + +#include + +/* PARISC cannot allow mdwe as it needs writable stacks */ +static inline bool arch_memory_deny_write_exec_supported(void) +{ + return false; +} +#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported + +#endif /* __ASM_MMAN_H__ */ --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/page.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/page.h @@ -16,6 +16,7 @@ #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #ifndef __ASSEMBLY__ --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/pgtable.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/pgtable.h @@ -448,14 +448,17 @@ return pte; } +static inline pte_t ptep_get(pte_t *ptep) +{ + return READ_ONCE(*ptep); +} +#define ptep_get ptep_get + static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { pte_t pte; - if (!pte_young(*ptep)) - return 0; - - pte = *ptep; + pte = ptep_get(ptep); if (!pte_young(pte)) { return 0; } @@ -463,17 +466,10 @@ return 1; } -struct mm_struct; -static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - pte_t old_pte; - - old_pte = *ptep; - set_pte(ptep, __pte(0)); - - return old_pte; -} +int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); +pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); +struct mm_struct; static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { set_pte(ptep, pte_wrprotect(*ptep)); @@ -511,7 +507,8 @@ #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH +#define __HAVE_ARCH_PTEP_CLEAR_FLUSH #define __HAVE_ARCH_PTEP_SET_WRPROTECT #define __HAVE_ARCH_PTE_SAME --- linux-xilinx-6.8.0.orig/arch/parisc/include/asm/signal.h +++ linux-xilinx-6.8.0/arch/parisc/include/asm/signal.h @@ -4,23 +4,11 @@ #include -#define _NSIG 64 -/* bits-per-word, where word apparently means 'long' not 'int' */ -#define _NSIG_BPW BITS_PER_LONG -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - # ifndef __ASSEMBLY__ /* Most things should be clean enough to redefine this at will, if care is taken to make libc match. */ -typedef unsigned long old_sigset_t; /* at least 32 bits */ - -typedef struct { - /* next_signal() assumes this is a long - no choice */ - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - #include #endif /* !__ASSEMBLY */ --- linux-xilinx-6.8.0.orig/arch/parisc/include/uapi/asm/signal.h +++ linux-xilinx-6.8.0/arch/parisc/include/uapi/asm/signal.h @@ -57,10 +57,20 @@ #include +#define _NSIG 64 +#define _NSIG_BPW (sizeof(unsigned long) * 8) +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + # ifndef __ASSEMBLY__ # include +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + /* Avoid too many header ordering problems. */ struct siginfo; --- linux-xilinx-6.8.0.orig/arch/parisc/kernel/cache.c +++ linux-xilinx-6.8.0/arch/parisc/kernel/cache.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,20 +32,31 @@ #include #include +#define PTR_PAGE_ALIGN_DOWN(addr) PTR_ALIGN_DOWN(addr, PAGE_SIZE) + +/* + * When nonzero, use _PAGE_ACCESSED bit to try to reduce the number + * of page flushes done flush_cache_page_if_present. There are some + * pros and cons in using this option. It may increase the risk of + * random segmentation faults. + */ +#define CONFIG_FLUSH_PAGE_ACCESSED 0 + int split_tlb __ro_after_init; int dcache_stride __ro_after_init; int icache_stride __ro_after_init; EXPORT_SYMBOL(dcache_stride); +/* Internal implementation in arch/parisc/kernel/pacache.S */ void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); EXPORT_SYMBOL(flush_dcache_page_asm); void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr); void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr); - -/* Internal implementation in arch/parisc/kernel/pacache.S */ void flush_data_cache_local(void *); /* flushes local data-cache only */ void flush_instruction_cache_local(void); /* flushes local code-cache only */ +static void flush_kernel_dcache_page_addr(const void *addr); + /* On some machines (i.e., ones with the Merced bus), there can be * only a single PxTLB broadcast at a time; this must be guaranteed * by software. We need a spinlock around all TLB flushes to ensure @@ -321,6 +333,18 @@ { if (!static_branch_likely(&parisc_has_cache)) return; + + /* + * The TLB is the engine of coherence on parisc. The CPU is + * entitled to speculate any page with a TLB mapping, so here + * we kill the mapping then flush the page along a special flush + * only alias mapping. This guarantees that the page is no-longer + * in the cache for any process and nor may it be speculatively + * read in (until the user or kernel specifically accesses it, + * of course). + */ + flush_tlb_page(vma, vmaddr); + preempt_disable(); flush_dcache_page_asm(physaddr, vmaddr); if (vma->vm_flags & VM_EXEC) @@ -328,46 +352,44 @@ preempt_enable(); } -static void flush_user_cache_page(struct vm_area_struct *vma, unsigned long vmaddr) +static void flush_kernel_dcache_page_addr(const void *addr) { - unsigned long flags, space, pgd, prot; -#ifdef CONFIG_TLB_PTLOCK - unsigned long pgd_lock; -#endif + unsigned long vaddr = (unsigned long)addr; + unsigned long flags; - vmaddr &= PAGE_MASK; + /* Purge TLB entry to remove translation on all CPUs */ + purge_tlb_start(flags); + pdtlb(SR_KERNEL, addr); + purge_tlb_end(flags); + /* Use tmpalias flush to prevent data cache move-in */ preempt_disable(); + flush_dcache_page_asm(__pa(vaddr), vaddr); + preempt_enable(); +} - /* Set context for flush */ - local_irq_save(flags); - prot = mfctl(8); - space = mfsp(SR_USER); - pgd = mfctl(25); -#ifdef CONFIG_TLB_PTLOCK - pgd_lock = mfctl(28); -#endif - switch_mm_irqs_off(NULL, vma->vm_mm, NULL); - local_irq_restore(flags); - - flush_user_dcache_range_asm(vmaddr, vmaddr + PAGE_SIZE); - if (vma->vm_flags & VM_EXEC) - flush_user_icache_range_asm(vmaddr, vmaddr + PAGE_SIZE); - flush_tlb_page(vma, vmaddr); +static void flush_kernel_icache_page_addr(const void *addr) +{ + unsigned long vaddr = (unsigned long)addr; + unsigned long flags; - /* Restore previous context */ - local_irq_save(flags); -#ifdef CONFIG_TLB_PTLOCK - mtctl(pgd_lock, 28); -#endif - mtctl(pgd, 25); - mtsp(space, SR_USER); - mtctl(prot, 8); - local_irq_restore(flags); + /* Purge TLB entry to remove translation on all CPUs */ + purge_tlb_start(flags); + pdtlb(SR_KERNEL, addr); + purge_tlb_end(flags); + /* Use tmpalias flush to prevent instruction cache move-in */ + preempt_disable(); + flush_icache_page_asm(__pa(vaddr), vaddr); preempt_enable(); } +void kunmap_flush_on_unmap(const void *addr) +{ + flush_kernel_dcache_page_addr(addr); +} +EXPORT_SYMBOL(kunmap_flush_on_unmap); + void flush_icache_pages(struct vm_area_struct *vma, struct page *page, unsigned int nr) { @@ -375,13 +397,16 @@ for (;;) { flush_kernel_dcache_page_addr(kaddr); - flush_kernel_icache_page(kaddr); + flush_kernel_icache_page_addr(kaddr); if (--nr == 0) break; kaddr += PAGE_SIZE; } } +/* + * Walk page directory for MM to find PTEP pointer for address ADDR. + */ static inline pte_t *get_ptep(struct mm_struct *mm, unsigned long addr) { pte_t *ptep = NULL; @@ -410,6 +435,41 @@ == (_PAGE_PRESENT | _PAGE_ACCESSED); } +/* + * Return user physical address. Returns 0 if page is not present. + */ +static inline unsigned long get_upa(struct mm_struct *mm, unsigned long addr) +{ + unsigned long flags, space, pgd, prot, pa; +#ifdef CONFIG_TLB_PTLOCK + unsigned long pgd_lock; +#endif + + /* Save context */ + local_irq_save(flags); + prot = mfctl(8); + space = mfsp(SR_USER); + pgd = mfctl(25); +#ifdef CONFIG_TLB_PTLOCK + pgd_lock = mfctl(28); +#endif + + /* Set context for lpa_user */ + switch_mm_irqs_off(NULL, mm, NULL); + pa = lpa_user(addr); + + /* Restore previous context */ +#ifdef CONFIG_TLB_PTLOCK + mtctl(pgd_lock, 28); +#endif + mtctl(pgd, 25); + mtsp(space, SR_USER); + mtctl(prot, 8); + local_irq_restore(flags); + + return pa; +} + void flush_dcache_folio(struct folio *folio) { struct address_space *mapping = folio_flush_mapping(folio); @@ -458,50 +518,23 @@ if (addr + nr * PAGE_SIZE > vma->vm_end) nr = (vma->vm_end - addr) / PAGE_SIZE; - if (parisc_requires_coherency()) { - for (i = 0; i < nr; i++) { - pte_t *ptep = get_ptep(vma->vm_mm, - addr + i * PAGE_SIZE); - if (!ptep) - continue; - if (pte_needs_flush(*ptep)) - flush_user_cache_page(vma, - addr + i * PAGE_SIZE); - /* Optimise accesses to the same table? */ - pte_unmap(ptep); - } - } else { + if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1)) + != (addr & (SHM_COLOUR - 1))) { + for (i = 0; i < nr; i++) + __flush_cache_page(vma, + addr + i * PAGE_SIZE, + (pfn + i) * PAGE_SIZE); /* - * The TLB is the engine of coherence on parisc: - * The CPU is entitled to speculate any page - * with a TLB mapping, so here we kill the - * mapping then flush the page along a special - * flush only alias mapping. This guarantees that - * the page is no-longer in the cache for any - * process and nor may it be speculatively read - * in (until the user or kernel specifically - * accesses it, of course) + * Software is allowed to have any number + * of private mappings to a page. */ - for (i = 0; i < nr; i++) - flush_tlb_page(vma, addr + i * PAGE_SIZE); - if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1)) - != (addr & (SHM_COLOUR - 1))) { - for (i = 0; i < nr; i++) - __flush_cache_page(vma, - addr + i * PAGE_SIZE, - (pfn + i) * PAGE_SIZE); - /* - * Software is allowed to have any number - * of private mappings to a page. - */ - if (!(vma->vm_flags & VM_SHARED)) - continue; - if (old_addr) - pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n", - old_addr, addr, vma->vm_file); - if (nr == folio_nr_pages(folio)) - old_addr = addr; - } + if (!(vma->vm_flags & VM_SHARED)) + continue; + if (old_addr) + pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n", + old_addr, addr, vma->vm_file); + if (nr == folio_nr_pages(folio)) + old_addr = addr; } WARN_ON(++count == 4096); } @@ -591,35 +624,28 @@ extern void clear_user_page_asm(void *, unsigned long); extern void copy_user_page_asm(void *, void *, unsigned long); -void flush_kernel_dcache_page_addr(const void *addr) -{ - unsigned long flags; - - flush_kernel_dcache_page_asm(addr); - purge_tlb_start(flags); - pdtlb(SR_KERNEL, addr); - purge_tlb_end(flags); -} -EXPORT_SYMBOL(flush_kernel_dcache_page_addr); - static void flush_cache_page_if_present(struct vm_area_struct *vma, - unsigned long vmaddr, unsigned long pfn) + unsigned long vmaddr) { +#if CONFIG_FLUSH_PAGE_ACCESSED bool needs_flush = false; - pte_t *ptep; + pte_t *ptep, pte; - /* - * The pte check is racy and sometimes the flush will trigger - * a non-access TLB miss. Hopefully, the page has already been - * flushed. - */ ptep = get_ptep(vma->vm_mm, vmaddr); if (ptep) { - needs_flush = pte_needs_flush(*ptep); + pte = ptep_get(ptep); + needs_flush = pte_needs_flush(pte); pte_unmap(ptep); } if (needs_flush) - flush_cache_page(vma, vmaddr, pfn); + __flush_cache_page(vma, vmaddr, PFN_PHYS(pte_pfn(pte))); +#else + struct mm_struct *mm = vma->vm_mm; + unsigned long physaddr = get_upa(mm, vmaddr); + + if (physaddr) + __flush_cache_page(vma, vmaddr, PAGE_ALIGN_DOWN(physaddr)); +#endif } void copy_user_highpage(struct page *to, struct page *from, @@ -629,7 +655,7 @@ kfrom = kmap_local_page(from); kto = kmap_local_page(to); - flush_cache_page_if_present(vma, vaddr, page_to_pfn(from)); + __flush_cache_page(vma, vaddr, PFN_PHYS(page_to_pfn(from))); copy_page_asm(kto, kfrom); kunmap_local(kto); kunmap_local(kfrom); @@ -638,16 +664,17 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long user_vaddr, void *dst, void *src, int len) { - flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page)); + __flush_cache_page(vma, user_vaddr, PFN_PHYS(page_to_pfn(page))); memcpy(dst, src, len); - flush_kernel_dcache_range_asm((unsigned long)dst, (unsigned long)dst + len); + flush_kernel_dcache_page_addr(PTR_PAGE_ALIGN_DOWN(dst)); } void copy_from_user_page(struct vm_area_struct *vma, struct page *page, unsigned long user_vaddr, void *dst, void *src, int len) { - flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page)); + __flush_cache_page(vma, user_vaddr, PFN_PHYS(page_to_pfn(page))); memcpy(dst, src, len); + flush_kernel_dcache_page_addr(PTR_PAGE_ALIGN_DOWN(src)); } /* __flush_tlb_range() @@ -681,32 +708,10 @@ static void flush_cache_pages(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - unsigned long addr, pfn; - pte_t *ptep; + unsigned long addr; - for (addr = start; addr < end; addr += PAGE_SIZE) { - bool needs_flush = false; - /* - * The vma can contain pages that aren't present. Although - * the pte search is expensive, we need the pte to find the - * page pfn and to check whether the page should be flushed. - */ - ptep = get_ptep(vma->vm_mm, addr); - if (ptep) { - needs_flush = pte_needs_flush(*ptep); - pfn = pte_pfn(*ptep); - pte_unmap(ptep); - } - if (needs_flush) { - if (parisc_requires_coherency()) { - flush_user_cache_page(vma, addr); - } else { - if (WARN_ON(!pfn_valid(pfn))) - return; - __flush_cache_page(vma, addr, PFN_PHYS(pfn)); - } - } - } + for (addr = start; addr < end; addr += PAGE_SIZE) + flush_cache_page_if_present(vma, addr); } static inline unsigned long mm_total_size(struct mm_struct *mm) @@ -757,21 +762,19 @@ if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) return; flush_tlb_range(vma, start, end); - flush_cache_all(); + if (vma->vm_flags & VM_EXEC) + flush_cache_all(); + else + flush_data_cache(); return; } - flush_cache_pages(vma, start, end); + flush_cache_pages(vma, start & PAGE_MASK, end); } void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn) { - if (WARN_ON(!pfn_valid(pfn))) - return; - if (parisc_requires_coherency()) - flush_user_cache_page(vma, vmaddr); - else - __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); + __flush_cache_page(vma, vmaddr, PFN_PHYS(pfn)); } void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) @@ -779,34 +782,133 @@ if (!PageAnon(page)) return; - if (parisc_requires_coherency()) { - if (vma->vm_flags & VM_SHARED) - flush_data_cache(); - else - flush_user_cache_page(vma, vmaddr); + __flush_cache_page(vma, vmaddr, PFN_PHYS(page_to_pfn(page))); +} + +int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep) +{ + pte_t pte = ptep_get(ptep); + + if (!pte_young(pte)) + return 0; + set_pte(ptep, pte_mkold(pte)); +#if CONFIG_FLUSH_PAGE_ACCESSED + __flush_cache_page(vma, addr, PFN_PHYS(pte_pfn(pte))); +#endif + return 1; +} + +/* + * After a PTE is cleared, we have no way to flush the cache for + * the physical page. On PA8800 and PA8900 processors, these lines + * can cause random cache corruption. Thus, we must flush the cache + * as well as the TLB when clearing a PTE that's valid. + */ +pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep) +{ + struct mm_struct *mm = (vma)->vm_mm; + pte_t pte = ptep_get_and_clear(mm, addr, ptep); + unsigned long pfn = pte_pfn(pte); + + if (pfn_valid(pfn)) + __flush_cache_page(vma, addr, PFN_PHYS(pfn)); + else if (pte_accessible(mm, pte)) + flush_tlb_page(vma, addr); + + return pte; +} + +/* + * The physical address for pages in the ioremap case can be obtained + * from the vm_struct struct. I wasn't able to successfully handle the + * vmalloc and vmap cases. We have an array of struct page pointers in + * the uninitialized vmalloc case but the flush failed using page_to_pfn. + */ +void flush_cache_vmap(unsigned long start, unsigned long end) +{ + unsigned long addr, physaddr; + struct vm_struct *vm; + + /* Prevent cache move-in */ + flush_tlb_kernel_range(start, end); + + if (end - start >= parisc_cache_flush_threshold) { + flush_cache_all(); return; } - flush_tlb_page(vma, vmaddr); - preempt_disable(); - flush_dcache_page_asm(page_to_phys(page), vmaddr); - preempt_enable(); + if (WARN_ON_ONCE(!is_vmalloc_addr((void *)start))) { + flush_cache_all(); + return; + } + + vm = find_vm_area((void *)start); + if (WARN_ON_ONCE(!vm)) { + flush_cache_all(); + return; + } + + /* The physical addresses of IOREMAP regions are contiguous */ + if (vm->flags & VM_IOREMAP) { + physaddr = vm->phys_addr; + for (addr = start; addr < end; addr += PAGE_SIZE) { + preempt_disable(); + flush_dcache_page_asm(physaddr, start); + flush_icache_page_asm(physaddr, start); + preempt_enable(); + physaddr += PAGE_SIZE; + } + return; + } + + flush_cache_all(); } +EXPORT_SYMBOL(flush_cache_vmap); +/* + * The vm_struct has been retired and the page table is set up. The + * last page in the range is a guard page. Its physical address can't + * be determined using lpa, so there is no way to flush the range + * using flush_dcache_page_asm. + */ +void flush_cache_vunmap(unsigned long start, unsigned long end) +{ + /* Prevent cache move-in */ + flush_tlb_kernel_range(start, end); + flush_data_cache(); +} +EXPORT_SYMBOL(flush_cache_vunmap); + +/* + * On systems with PA8800/PA8900 processors, there is no way to flush + * a vmap range other than using the architected loop to flush the + * entire cache. The page directory is not set up, so we can't use + * fdc, etc. FDCE/FICE don't work to flush a portion of the cache. + * L2 is physically indexed but FDCE/FICE instructions in virtual + * mode output their virtual address on the core bus, not their + * real address. As a result, the L2 cache index formed from the + * virtual address will most likely not be the same as the L2 index + * formed from the real address. + */ void flush_kernel_vmap_range(void *vaddr, int size) { unsigned long start = (unsigned long)vaddr; unsigned long end = start + size; - if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && - (unsigned long)size >= parisc_cache_flush_threshold) { - flush_tlb_kernel_range(start, end); - flush_data_cache(); + flush_tlb_kernel_range(start, end); + + if (!static_branch_likely(&parisc_has_dcache)) + return; + + /* If interrupts are disabled, we can only do local flush */ + if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) { + flush_data_cache_local(NULL); return; } - flush_kernel_dcache_range_asm(start, end); - flush_tlb_kernel_range(start, end); + flush_data_cache(); } EXPORT_SYMBOL(flush_kernel_vmap_range); @@ -818,15 +920,18 @@ /* Ensure DMA is complete */ asm_syncdma(); - if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && - (unsigned long)size >= parisc_cache_flush_threshold) { - flush_tlb_kernel_range(start, end); - flush_data_cache(); + flush_tlb_kernel_range(start, end); + + if (!static_branch_likely(&parisc_has_dcache)) + return; + + /* If interrupts are disabled, we can only do local flush */ + if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) { + flush_data_cache_local(NULL); return; } - purge_kernel_dcache_range_asm(start, end); - flush_tlb_kernel_range(start, end); + flush_data_cache(); } EXPORT_SYMBOL(invalidate_kernel_vmap_range); --- linux-xilinx-6.8.0.orig/arch/parisc/kernel/ftrace.c +++ linux-xilinx-6.8.0/arch/parisc/kernel/ftrace.c @@ -206,6 +206,9 @@ struct kprobe *p; int bit; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/parisc/kernel/parisc_ksyms.c +++ linux-xilinx-6.8.0/arch/parisc/kernel/parisc_ksyms.c @@ -22,6 +22,7 @@ #include EXPORT_SYMBOL(__xchg8); EXPORT_SYMBOL(__xchg32); +EXPORT_SYMBOL(__cmpxchg_u8); EXPORT_SYMBOL(__cmpxchg_u32); EXPORT_SYMBOL(__cmpxchg_u64); #ifdef CONFIG_SMP --- linux-xilinx-6.8.0.orig/arch/parisc/kernel/sys_parisc32.c +++ linux-xilinx-6.8.0/arch/parisc/kernel/sys_parisc32.c @@ -23,12 +23,3 @@ current->comm, current->pid, r20); return -ENOSYS; } - -asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags, - compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd, - const char __user * pathname) -{ - return sys_fanotify_mark(fanotify_fd, flags, - ((__u64)mask1 << 32) | mask0, - dfd, pathname); -} --- linux-xilinx-6.8.0.orig/arch/parisc/kernel/syscalls/syscall.tbl +++ linux-xilinx-6.8.0/arch/parisc/kernel/syscalls/syscall.tbl @@ -108,7 +108,7 @@ 95 common fchown sys_fchown 96 common getpriority sys_getpriority 97 common setpriority sys_setpriority -98 common recv sys_recv +98 common recv sys_recv compat_sys_recv 99 common statfs sys_statfs compat_sys_statfs 100 common fstatfs sys_fstatfs compat_sys_fstatfs 101 common stat64 sys_stat64 @@ -135,7 +135,7 @@ 120 common clone sys_clone_wrapper 121 common setdomainname sys_setdomainname 122 common sendfile sys_sendfile compat_sys_sendfile -123 common recvfrom sys_recvfrom +123 common recvfrom sys_recvfrom compat_sys_recvfrom 124 32 adjtimex sys_adjtimex_time32 124 64 adjtimex sys_adjtimex 125 common mprotect sys_mprotect @@ -364,7 +364,7 @@ 320 common accept4 sys_accept4 321 common prlimit64 sys_prlimit64 322 common fanotify_init sys_fanotify_init -323 common fanotify_mark sys_fanotify_mark sys32_fanotify_mark +323 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark 324 32 clock_adjtime sys_clock_adjtime32 324 64 clock_adjtime sys_clock_adjtime 325 common name_to_handle_at sys_name_to_handle_at --- linux-xilinx-6.8.0.orig/arch/parisc/kernel/unaligned.c +++ linux-xilinx-6.8.0/arch/parisc/kernel/unaligned.c @@ -169,6 +169,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) { unsigned long saddr = regs->ior; + unsigned long shift, temp1; __u64 val = 0; ASM_EXCEPTIONTABLE_VAR(ret); @@ -180,25 +181,22 @@ #ifdef CONFIG_64BIT __asm__ __volatile__ ( -" depd,z %3,60,3,%%r19\n" /* r19=(ofs&7)*8 */ -" mtsp %4, %%sr1\n" -" depd %%r0,63,3,%3\n" -"1: ldd 0(%%sr1,%3),%0\n" -"2: ldd 8(%%sr1,%3),%%r20\n" -" subi 64,%%r19,%%r19\n" -" mtsar %%r19\n" -" shrpd %0,%%r20,%%sar,%0\n" +" depd,z %2,60,3,%3\n" /* shift=(ofs&7)*8 */ +" mtsp %5, %%sr1\n" +" depd %%r0,63,3,%2\n" +"1: ldd 0(%%sr1,%2),%0\n" +"2: ldd 8(%%sr1,%2),%4\n" +" subi 64,%3,%3\n" +" mtsar %3\n" +" shrpd %0,%4,%%sar,%0\n" "3: \n" ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1") ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1") - : "=r" (val), "+r" (ret) - : "0" (val), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1) + : "r" (regs->isr) ); #else - { - unsigned long shift, temp1; __asm__ __volatile__ ( -" zdep %2,29,2,%3\n" /* r19=(ofs&3)*8 */ +" zdep %2,29,2,%3\n" /* shift=(ofs&3)*8 */ " mtsp %5, %%sr1\n" " dep %%r0,31,2,%2\n" "1: ldw 0(%%sr1,%2),%0\n" @@ -214,7 +212,6 @@ ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b, "%1") : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1) : "r" (regs->isr) ); - } #endif DPRINTF("val = 0x%llx\n", val); --- linux-xilinx-6.8.0.orig/arch/parisc/net/bpf_jit_core.c +++ linux-xilinx-6.8.0/arch/parisc/net/bpf_jit_core.c @@ -167,7 +167,13 @@ bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns); if (!prog->is_func || extra_pass) { - bpf_jit_binary_lock_ro(jit_data->header); + if (bpf_jit_binary_lock_ro(jit_data->header)) { + bpf_jit_binary_free(jit_data->header); + prog->bpf_func = NULL; + prog->jited = 0; + prog->jited_len = 0; + goto out_offset; + } prologue_len = ctx->epilogue_offset - ctx->body_len; for (i = 0; i < prog->len; i++) ctx->offset[i] += prologue_len; --- linux-xilinx-6.8.0.orig/arch/powerpc/Kconfig +++ linux-xilinx-6.8.0/arch/powerpc/Kconfig @@ -154,7 +154,7 @@ select ARCH_HAS_SYSCALL_WRAPPER if !SPU_BASE && !COMPAT select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_KEEP_MEMBLOCK select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if PPC_RADIX_MMU --- linux-xilinx-6.8.0.orig/arch/powerpc/Makefile +++ linux-xilinx-6.8.0/arch/powerpc/Makefile @@ -238,7 +238,7 @@ all: zImage # With make 3.82 we cannot mix normal and wildcard targets -BOOT_TARGETS1 := zImage zImage.initrd uImage +BOOT_TARGETS1 := zImage zImage.initrd uImage vmlinux.strip BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% uImage.% PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) --- linux-xilinx-6.8.0.orig/arch/powerpc/crypto/chacha-p10-glue.c +++ linux-xilinx-6.8.0/arch/powerpc/crypto/chacha-p10-glue.c @@ -197,6 +197,9 @@ static int __init chacha_p10_init(void) { + if (!cpu_has_feature(CPU_FTR_ARCH_31)) + return 0; + static_branch_enable(&have_p10); return crypto_register_skciphers(algs, ARRAY_SIZE(algs)); @@ -204,10 +207,13 @@ static void __exit chacha_p10_exit(void) { + if (!static_branch_likely(&have_p10)) + return; + crypto_unregister_skciphers(algs, ARRAY_SIZE(algs)); } -module_cpu_feature_match(PPC_MODULE_FEATURE_P10, chacha_p10_init); +module_init(chacha_p10_init); module_exit(chacha_p10_exit); MODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (P10 accelerated)"); --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/cputhreads.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/cputhreads.h @@ -3,6 +3,7 @@ #define _ASM_POWERPC_CPUTHREADS_H #ifndef __ASSEMBLY__ +#include #include #include --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/guest-state-buffer.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/guest-state-buffer.h @@ -81,6 +81,7 @@ #define KVMPPC_GSID_HASHKEYR 0x1050 #define KVMPPC_GSID_HASHPKEYR 0x1051 #define KVMPPC_GSID_CTRL 0x1052 +#define KVMPPC_GSID_DPDES 0x1053 #define KVMPPC_GSID_CR 0x2000 #define KVMPPC_GSID_PIDR 0x2001 @@ -110,7 +111,7 @@ #define KVMPPC_GSE_META_COUNT (KVMPPC_GSE_META_END - KVMPPC_GSE_META_START + 1) #define KVMPPC_GSE_DW_REGS_START KVMPPC_GSID_GPR(0) -#define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_CTRL +#define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_DPDES #define KVMPPC_GSE_DW_REGS_COUNT \ (KVMPPC_GSE_DW_REGS_END - KVMPPC_GSE_DW_REGS_START + 1) --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/hvcall.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/hvcall.h @@ -524,7 +524,7 @@ * Used for all but the craziest of phyp interfaces (see plpar_hcall9) */ #define PLPAR_HCALL_BUFSIZE 4 -long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); /** * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats @@ -538,7 +538,7 @@ * plpar_hcall, but plpar_hcall_raw works in real mode and does not * calculate hypervisor call statistics. */ -long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); /** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments @@ -549,8 +549,8 @@ * PLPAR_HCALL9_BUFSIZE to size the return argument buffer. */ #define PLPAR_HCALL9_BUFSIZE 9 -long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); -long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); +long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); /* pseries hcall tracing */ extern struct static_key hcall_tracepoint_key; @@ -570,7 +570,7 @@ unsigned long backing_mem; }; -int h_get_mpp(struct hvcall_mpp_data *); +long h_get_mpp(struct hvcall_mpp_data *mpp_data); struct hvcall_mpp_x_data { unsigned long coalesced_bytes; --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/interrupt.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/interrupt.h @@ -336,6 +336,14 @@ if (IS_ENABLED(CONFIG_KASAN)) return; + /* + * Likewise, do not use it in real mode if percpu first chunk is not + * embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled there + * are chances where percpu allocation can come from vmalloc area. + */ + if (percpu_first_chunk_is_paged) + return; + /* Otherwise, it should be safe to call it */ nmi_enter(); } @@ -351,6 +359,8 @@ // no nmi_exit for a pseries hash guest taking a real mode exception } else if (IS_ENABLED(CONFIG_KASAN)) { // no nmi_exit for KASAN in real mode + } else if (percpu_first_chunk_is_paged) { + // no nmi_exit if percpu first chunk is not embedded } else { nmi_exit(); } --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/io.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/io.h @@ -37,7 +37,7 @@ * define properly based on the platform */ #ifndef CONFIG_PCI -#define _IO_BASE 0 +#define _IO_BASE POISON_POINTER_DELTA #define _ISA_MEM_BASE 0 #define PCI_DRAM_OFFSET 0 #elif defined(CONFIG_PPC32) @@ -585,12 +585,12 @@ #define __do_inw(port) _rec_inw(port) #define __do_inl(port) _rec_inl(port) #else /* CONFIG_PPC32 */ -#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port); -#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port); -#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port); -#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port); -#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port); -#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port); +#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)(_IO_BASE+port)); +#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)(_IO_BASE+port)); +#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)(_IO_BASE+port)); +#define __do_inb(port) readb((PCI_IO_ADDR)(_IO_BASE + port)); +#define __do_inw(port) readw((PCI_IO_ADDR)(_IO_BASE + port)); +#define __do_inl(port) readl((PCI_IO_ADDR)(_IO_BASE + port)); #endif /* !CONFIG_PPC32 */ #ifdef CONFIG_EEH @@ -606,12 +606,12 @@ #define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n)) #define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n)) -#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) -#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) -#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) -#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) -#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) -#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) +#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) +#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) +#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) +#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) +#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) +#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) #define __do_memset_io(addr, c, n) \ _memset_io(PCI_FIX_ADDR(addr), c, n) --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/kfence.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/kfence.h @@ -15,10 +15,19 @@ #define ARCH_FUNC_PREFIX "." #endif +#ifdef CONFIG_KFENCE +extern bool kfence_disabled; + +static inline void disable_kfence(void) +{ + kfence_disabled = true; +} + static inline bool arch_kfence_init_pool(void) { - return true; + return !kfence_disabled; } +#endif #ifdef CONFIG_PPC64 static inline bool kfence_protect_page(unsigned long addr, bool protect) --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/kvm_book3s.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/kvm_book3s.h @@ -594,6 +594,7 @@ KVMPPC_BOOK3S_VCORE_ACCESSOR(vtb, 64, KVMPPC_GSID_VTB) +KVMPPC_BOOK3S_VCORE_ACCESSOR(dpdes, 64, KVMPPC_GSID_DPDES) KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(arch_compat, 32, KVMPPC_GSID_LOGICAL_PVR) KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(lpcr, 64, KVMPPC_GSID_LPCR) KVMPPC_BOOK3S_VCORE_ACCESSOR_SET(tb_offset, 64, KVMPPC_GSID_TB_OFFSET) --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/kvm_host.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/kvm_host.h @@ -599,6 +599,9 @@ ulong dawrx0; ulong dawr1; ulong dawrx1; + ulong dexcr; + ulong hashkeyr; + ulong hashpkeyr; ulong ciabr; ulong cfar; ulong ppr; --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/percpu.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/percpu.h @@ -15,6 +15,16 @@ #endif /* CONFIG_SMP */ #endif /* __powerpc64__ */ +#if defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK) && defined(CONFIG_SMP) +#include +DECLARE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged); + +#define percpu_first_chunk_is_paged \ + (static_key_enabled(&__percpu_first_chunk_is_paged.key)) +#else +#define percpu_first_chunk_is_paged false +#endif /* CONFIG_PPC64 && CONFIG_SMP */ + #include #include --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/plpks.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/plpks.h @@ -44,9 +44,8 @@ #define PLPKS_MAX_DATA_SIZE 4000 // Timeouts for PLPKS operations -#define PLPKS_MAX_TIMEOUT 5000 // msec -#define PLPKS_FLUSH_SLEEP 10 // msec -#define PLPKS_FLUSH_SLEEP_RANGE 400 +#define PLPKS_MAX_TIMEOUT (5 * USEC_PER_SEC) +#define PLPKS_FLUSH_SLEEP 10000 // usec struct plpks_var { char *component; --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/ppc-opcode.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/ppc-opcode.h @@ -510,6 +510,7 @@ #define PPC_RAW_STB(r, base, i) (0x98000000 | ___PPC_RS(r) | ___PPC_RA(base) | IMM_L(i)) #define PPC_RAW_LBZ(r, base, i) (0x88000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) #define PPC_RAW_LDX(r, base, b) (0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) +#define PPC_RAW_LHA(r, base, i) (0xa8000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) #define PPC_RAW_LHZ(r, base, i) (0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i)) #define PPC_RAW_LHBRX(r, base, b) (0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) #define PPC_RAW_LWBRX(r, base, b) (0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b)) @@ -532,6 +533,7 @@ #define PPC_RAW_MULW(d, a, b) (0x7c0001d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_RAW_MULHWU(d, a, b) (0x7c000016 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_RAW_MULI(d, a, i) (0x1c000000 | ___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i)) +#define PPC_RAW_DIVW(d, a, b) (0x7c0003d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_RAW_DIVWU(d, a, b) (0x7c000396 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_RAW_DIVDU(d, a, b) (0x7c000392 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_RAW_DIVDE(t, a, b) (0x7c000352 | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b)) @@ -550,6 +552,8 @@ #define PPC_RAW_XOR(d, a, b) (0x7c000278 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(b)) #define PPC_RAW_XORI(d, a, i) (0x68000000 | ___PPC_RA(d) | ___PPC_RS(a) | IMM_L(i)) #define PPC_RAW_XORIS(d, a, i) (0x6c000000 | ___PPC_RA(d) | ___PPC_RS(a) | IMM_L(i)) +#define PPC_RAW_EXTSB(d, a) (0x7c000774 | ___PPC_RA(d) | ___PPC_RS(a)) +#define PPC_RAW_EXTSH(d, a) (0x7c000734 | ___PPC_RA(d) | ___PPC_RS(a)) #define PPC_RAW_EXTSW(d, a) (0x7c0007b4 | ___PPC_RA(d) | ___PPC_RS(a)) #define PPC_RAW_SLW(d, a, s) (0x7c000030 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(s)) #define PPC_RAW_SLD(d, a, s) (0x7c000036 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(s)) --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/reg_fsl_emb.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/reg_fsl_emb.h @@ -12,9 +12,16 @@ #ifndef __ASSEMBLY__ /* Performance Monitor Registers */ #define mfpmr(rn) ({unsigned int rval; \ - asm volatile("mfpmr %0," __stringify(rn) \ + asm volatile(".machine push; " \ + ".machine e300; " \ + "mfpmr %0," __stringify(rn) ";" \ + ".machine pop; " \ : "=r" (rval)); rval;}) -#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v)) +#define mtpmr(rn, v) asm volatile(".machine push; " \ + ".machine e300; " \ + "mtpmr " __stringify(rn) ",%0; " \ + ".machine pop; " \ + : : "r" (v)) #endif /* __ASSEMBLY__ */ /* Freescale Book E Performance Monitor APU Registers */ --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/uaccess.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/uaccess.h @@ -92,9 +92,25 @@ : label) #endif +#ifdef CONFIG_CC_IS_CLANG +#define DS_FORM_CONSTRAINT "Z<>" +#else +#define DS_FORM_CONSTRAINT "YZ<>" +#endif + #ifdef __powerpc64__ +#ifdef CONFIG_PPC_KERNEL_PREFIXED #define __put_user_asm2_goto(x, ptr, label) \ __put_user_asm_goto(x, ptr, label, "std") +#else +#define __put_user_asm2_goto(x, addr, label) \ + asm goto ("1: std%U1%X1 %0,%1 # put_user\n" \ + EX_TABLE(1b, %l2) \ + : \ + : "r" (x), DS_FORM_CONSTRAINT (*addr) \ + : \ + : label) +#endif // CONFIG_PPC_KERNEL_PREFIXED #else /* __powerpc64__ */ #define __put_user_asm2_goto(x, addr, label) \ asm goto( \ --- linux-xilinx-6.8.0.orig/arch/powerpc/include/asm/vmalloc.h +++ linux-xilinx-6.8.0/arch/powerpc/include/asm/vmalloc.h @@ -7,14 +7,14 @@ #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP #define arch_vmap_pud_supported arch_vmap_pud_supported -static inline bool arch_vmap_pud_supported(pgprot_t prot) +static __always_inline bool arch_vmap_pud_supported(pgprot_t prot) { /* HPT does not cope with large pages in the vmalloc area */ return radix_enabled(); } #define arch_vmap_pmd_supported arch_vmap_pmd_supported -static inline bool arch_vmap_pmd_supported(pgprot_t prot) +static __always_inline bool arch_vmap_pmd_supported(pgprot_t prot) { return radix_enabled(); } --- linux-xilinx-6.8.0.orig/arch/powerpc/include/uapi/asm/kvm.h +++ linux-xilinx-6.8.0/arch/powerpc/include/uapi/asm/kvm.h @@ -646,6 +646,9 @@ #define KVM_REG_PPC_SIER3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3) #define KVM_REG_PPC_DAWR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc4) #define KVM_REG_PPC_DAWRX1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc5) +#define KVM_REG_PPC_DEXCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc6) +#define KVM_REG_PPC_HASHKEYR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc7) +#define KVM_REG_PPC_HASHPKEYR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc8) /* Transactional Memory checkpointed state: * This is all GPRs, all VSX regs and a subset of SPRs --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/eeh_pe.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/eeh_pe.c @@ -849,6 +849,7 @@ { struct eeh_dev *edev; struct pci_dev *pdev; + struct pci_bus *bus = NULL; if (pe->type & EEH_PE_PHB) return pe->phb->bus; @@ -859,9 +860,11 @@ /* Retrieve the parent PCI bus of first (top) PCI device */ edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, entry); + pci_lock_rescan_remove(); pdev = eeh_dev_to_pci_dev(edev); if (pdev) - return pdev->bus; + bus = pdev->bus; + pci_unlock_rescan_remove(); - return NULL; + return bus; } --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/head_64.S +++ linux-xilinx-6.8.0/arch/powerpc/kernel/head_64.S @@ -647,8 +647,9 @@ * Note: This process overwrites the OF exception vectors. */ LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET) - mr. r4,r26 /* In some cases the loader may */ - beq 9f /* have already put us at zero */ + mr r4,r26 /* Load the virtual source address into r4 */ + cmpld r3,r4 /* Check if source == dest */ + beq 9f /* If so skip the copy */ li r6,0x100 /* Start offset, the first 0x100 */ /* bytes were copied earlier. */ --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/kprobes-ftrace.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/kprobes-ftrace.c @@ -21,6 +21,9 @@ struct pt_regs *regs; int bit; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(nip, parent_nip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/module_64.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/module_64.c @@ -347,12 +347,13 @@ static void dedotify_versions(struct modversion_info *vers, unsigned long size) { - struct modversion_info *end; + struct modversion_info *end = (void *)vers + size; - for (end = (void *)vers + size; vers < end; vers++) + for (; vers < end && vers->next; vers = (void *)vers + vers->next) { if (vers->name[0] == '.') { memmove(vers->name, vers->name+1, strlen(vers->name)); } + } } /* --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/pci-common.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/pci-common.c @@ -360,6 +360,7 @@ } return NULL; } +EXPORT_SYMBOL(pci_find_hose_for_OF_device); struct pci_controller *pci_find_controller_for_domain(int domain_nr) { @@ -1630,6 +1631,7 @@ { return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); } +EXPORT_SYMBOL_GPL(early_find_capability); struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) { --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/prom.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/prom.c @@ -375,6 +375,18 @@ if (IS_ENABLED(CONFIG_PPC64)) boot_cpu_hwid = be32_to_cpu(intserv[found_thread]); + if (nr_cpu_ids % nthreads != 0) { + set_nr_cpu_ids(ALIGN(nr_cpu_ids, nthreads)); + pr_warn("nr_cpu_ids was not a multiple of threads_per_core, adjusted to %d\n", + nr_cpu_ids); + } + + if (boot_cpuid >= nr_cpu_ids) { + set_nr_cpu_ids(min(CONFIG_NR_CPUS, ALIGN(boot_cpuid + 1, nthreads))); + pr_warn("Boot CPU %d >= nr_cpu_ids, adjusted nr_cpu_ids to %d\n", + boot_cpuid, nr_cpu_ids); + } + /* * PAPR defines "logical" PVR values for cpus that * meet various levels of the architecture: --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/setup-common.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/setup-common.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ #include #include #include +#include #include "setup.h" @@ -896,6 +898,16 @@ */ initialize_cache_info(); + /* + * Lock down the kernel if booted in secure mode. This is required to + * maintain kernel integrity. + */ + if (IS_ENABLED(CONFIG_LOCK_DOWN_IN_SECURE_BOOT)) { + if (is_ppc_secureboot_enabled()) + security_lock_kernel_down("PowerNV Secure Boot mode", + LOCKDOWN_INTEGRITY_MAX); + } + /* Initialize RTAS if available. */ rtas_initialize(); --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/setup_64.c +++ linux-xilinx-6.8.0/arch/powerpc/kernel/setup_64.c @@ -834,6 +834,7 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; EXPORT_SYMBOL(__per_cpu_offset); +DEFINE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged); void __init setup_per_cpu_areas(void) { @@ -876,6 +877,7 @@ if (rc < 0) panic("cannot initialize percpu area (err=%d)", rc); + static_key_enable(&__percpu_first_chunk_is_paged.key); delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; for_each_possible_cpu(cpu) { __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; --- linux-xilinx-6.8.0.orig/arch/powerpc/kernel/syscalls/syscall.tbl +++ linux-xilinx-6.8.0/arch/powerpc/kernel/syscalls/syscall.tbl @@ -230,8 +230,10 @@ 178 nospu rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend 179 32 pread64 sys_ppc_pread64 compat_sys_ppc_pread64 179 64 pread64 sys_pread64 +179 spu pread64 sys_pread64 180 32 pwrite64 sys_ppc_pwrite64 compat_sys_ppc_pwrite64 180 64 pwrite64 sys_pwrite64 +180 spu pwrite64 sys_pwrite64 181 common chown sys_chown 182 common getcwd sys_getcwd 183 common capget sys_capget @@ -246,6 +248,7 @@ 190 common ugetrlimit sys_getrlimit compat_sys_getrlimit 191 32 readahead sys_ppc_readahead compat_sys_ppc_readahead 191 64 readahead sys_readahead +191 spu readahead sys_readahead 192 32 mmap2 sys_mmap2 compat_sys_mmap2 193 32 truncate64 sys_ppc_truncate64 compat_sys_ppc_truncate64 194 32 ftruncate64 sys_ppc_ftruncate64 compat_sys_ppc_ftruncate64 @@ -293,6 +296,7 @@ 232 nospu set_tid_address sys_set_tid_address 233 32 fadvise64 sys_ppc32_fadvise64 compat_sys_ppc32_fadvise64 233 64 fadvise64 sys_fadvise64 +233 spu fadvise64 sys_fadvise64 234 nospu exit_group sys_exit_group 235 nospu lookup_dcookie sys_ni_syscall 236 common epoll_create sys_epoll_create @@ -502,7 +506,7 @@ 412 32 utimensat_time64 sys_utimensat sys_utimensat 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive --- linux-xilinx-6.8.0.orig/arch/powerpc/kexec/core_64.c +++ linux-xilinx-6.8.0/arch/powerpc/kexec/core_64.c @@ -26,6 +26,7 @@ #include #include #include /* _end */ +#include #include #include #include @@ -315,6 +316,16 @@ if (!kdump_in_progress()) kexec_prepare_cpus(); +#ifdef CONFIG_PPC_PSERIES + /* + * This must be done after other CPUs have shut down, otherwise they + * could execute the 'scv' instruction, which is not supported with + * reloc disabled (see configure_exceptions()). + */ + if (firmware_has_feature(FW_FEATURE_SET_MODE)) + pseries_disable_reloc_on_exc(); +#endif + printk("kexec: Starting switchover sequence.\n"); /* switch to a staticly allocated stack. Based on irq stack code. --- linux-xilinx-6.8.0.orig/arch/powerpc/kvm/book3s_64_vio.c +++ linux-xilinx-6.8.0/arch/powerpc/kvm/book3s_64_vio.c @@ -130,14 +130,16 @@ } rcu_read_unlock(); - fdput(f); - - if (!found) + if (!found) { + fdput(f); return -EINVAL; + } table_group = iommu_group_get_iommudata(grp); - if (WARN_ON(!table_group)) + if (WARN_ON(!table_group)) { + fdput(f); return -EFAULT; + } for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { struct iommu_table *tbltmp = table_group->tables[i]; @@ -158,8 +160,10 @@ break; } } - if (!tbl) + if (!tbl) { + fdput(f); return -EINVAL; + } rcu_read_lock(); list_for_each_entry_rcu(stit, &stt->iommu_tables, next) { @@ -170,6 +174,7 @@ /* stit is being destroyed */ iommu_tce_table_put(tbl); rcu_read_unlock(); + fdput(f); return -ENOTTY; } /* @@ -177,6 +182,7 @@ * its KVM reference counter and can return. */ rcu_read_unlock(); + fdput(f); return 0; } rcu_read_unlock(); @@ -184,6 +190,7 @@ stit = kzalloc(sizeof(*stit), GFP_KERNEL); if (!stit) { iommu_tce_table_put(tbl); + fdput(f); return -ENOMEM; } @@ -192,6 +199,7 @@ list_add_rcu(&stit->next, &stt->iommu_tables); + fdput(f); return 0; } --- linux-xilinx-6.8.0.orig/arch/powerpc/kvm/book3s_hv.c +++ linux-xilinx-6.8.0/arch/powerpc/kvm/book3s_hv.c @@ -2304,7 +2304,7 @@ *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); break; case KVM_REG_PPC_SDAR: - *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); + *val = get_reg_val(id, kvmppc_get_sdar_hv(vcpu)); break; case KVM_REG_PPC_SIER: *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 0)); @@ -2348,6 +2348,15 @@ case KVM_REG_PPC_DAWRX1: *val = get_reg_val(id, kvmppc_get_dawrx1_hv(vcpu)); break; + case KVM_REG_PPC_DEXCR: + *val = get_reg_val(id, kvmppc_get_dexcr_hv(vcpu)); + break; + case KVM_REG_PPC_HASHKEYR: + *val = get_reg_val(id, kvmppc_get_hashkeyr_hv(vcpu)); + break; + case KVM_REG_PPC_HASHPKEYR: + *val = get_reg_val(id, kvmppc_get_hashpkeyr_hv(vcpu)); + break; case KVM_REG_PPC_CIABR: *val = get_reg_val(id, kvmppc_get_ciabr_hv(vcpu)); break; @@ -2539,7 +2548,7 @@ vcpu->arch.mmcrs = set_reg_val(id, *val); break; case KVM_REG_PPC_MMCR3: - *val = get_reg_val(id, vcpu->arch.mmcr[3]); + kvmppc_set_mmcr_hv(vcpu, 3, set_reg_val(id, *val)); break; case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8: i = id - KVM_REG_PPC_PMC1; @@ -2591,6 +2600,15 @@ case KVM_REG_PPC_DAWRX1: kvmppc_set_dawrx1_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP); break; + case KVM_REG_PPC_DEXCR: + kvmppc_set_dexcr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_HASHKEYR: + kvmppc_set_hashkeyr_hv(vcpu, set_reg_val(id, *val)); + break; + case KVM_REG_PPC_HASHPKEYR: + kvmppc_set_hashpkeyr_hv(vcpu, set_reg_val(id, *val)); + break; case KVM_REG_PPC_CIABR: kvmppc_set_ciabr_hv(vcpu, set_reg_val(id, *val)); /* Don't allow setting breakpoints in hypervisor code */ @@ -4115,6 +4133,11 @@ int trap; long rc; + if (vcpu->arch.doorbell_request) { + vcpu->arch.doorbell_request = 0; + kvmppc_set_dpdes(vcpu, 1); + } + io = &vcpu->arch.nestedv2_io; msr = mfmsr(); @@ -4856,7 +4879,7 @@ * entering a nested guest in which case the decrementer is now owned * by L2 and the L1 decrementer is provided in hdec_expires */ - if (!kvmhv_is_nestedv2() && kvmppc_core_pending_dec(vcpu) && + if (kvmppc_core_pending_dec(vcpu) && ((tb < kvmppc_dec_expires_host_tb(vcpu)) || (trap == BOOK3S_INTERRUPT_SYSCALL && kvmppc_get_gpr(vcpu, 3) == H_ENTER_NESTED))) --- linux-xilinx-6.8.0.orig/arch/powerpc/kvm/book3s_hv.h +++ linux-xilinx-6.8.0/arch/powerpc/kvm/book3s_hv.h @@ -116,6 +116,9 @@ KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr1, 64, KVMPPC_GSID_DAWR1) KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx0, 64, KVMPPC_GSID_DAWRX0) KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx1, 64, KVMPPC_GSID_DAWRX1) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dexcr, 64, KVMPPC_GSID_DEXCR) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hashkeyr, 64, KVMPPC_GSID_HASHKEYR) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hashpkeyr, 64, KVMPPC_GSID_HASHPKEYR) KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ciabr, 64, KVMPPC_GSID_CIABR) KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(wort, 64, KVMPPC_GSID_WORT) KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ppr, 64, KVMPPC_GSID_PPR) --- linux-xilinx-6.8.0.orig/arch/powerpc/kvm/book3s_hv_nestedv2.c +++ linux-xilinx-6.8.0/arch/powerpc/kvm/book3s_hv_nestedv2.c @@ -71,8 +71,8 @@ } if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_RUN_OUTPUT)) { - kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_OUTPUT, - cfg->vcpu_run_output_cfg); + rc = kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_OUTPUT, + cfg->vcpu_run_output_cfg); if (rc < 0) return rc; } @@ -193,6 +193,15 @@ case KVMPPC_GSID_DAWRX1: rc = kvmppc_gse_put_u32(gsb, iden, vcpu->arch.dawrx1); break; + case KVMPPC_GSID_DEXCR: + rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.dexcr); + break; + case KVMPPC_GSID_HASHKEYR: + rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.hashkeyr); + break; + case KVMPPC_GSID_HASHPKEYR: + rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.hashpkeyr); + break; case KVMPPC_GSID_CIABR: rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.ciabr); break; @@ -311,6 +320,10 @@ rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.vcore->vtb); break; + case KVMPPC_GSID_DPDES: + rc = kvmppc_gse_put_u64(gsb, iden, + vcpu->arch.vcore->dpdes); + break; case KVMPPC_GSID_LPCR: rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.vcore->lpcr); @@ -441,6 +454,15 @@ case KVMPPC_GSID_DAWRX1: vcpu->arch.dawrx1 = kvmppc_gse_get_u32(gse); break; + case KVMPPC_GSID_DEXCR: + vcpu->arch.dexcr = kvmppc_gse_get_u64(gse); + break; + case KVMPPC_GSID_HASHKEYR: + vcpu->arch.hashkeyr = kvmppc_gse_get_u64(gse); + break; + case KVMPPC_GSID_HASHPKEYR: + vcpu->arch.hashpkeyr = kvmppc_gse_get_u64(gse); + break; case KVMPPC_GSID_CIABR: vcpu->arch.ciabr = kvmppc_gse_get_u64(gse); break; @@ -543,6 +565,9 @@ case KVMPPC_GSID_VTB: vcpu->arch.vcore->vtb = kvmppc_gse_get_u64(gse); break; + case KVMPPC_GSID_DPDES: + vcpu->arch.vcore->dpdes = kvmppc_gse_get_u64(gse); + break; case KVMPPC_GSID_LPCR: vcpu->arch.vcore->lpcr = kvmppc_gse_get_u64(gse); break; --- linux-xilinx-6.8.0.orig/arch/powerpc/kvm/test-guest-state-buffer.c +++ linux-xilinx-6.8.0/arch/powerpc/kvm/test-guest-state-buffer.c @@ -151,7 +151,7 @@ i++; } - for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSID_CTRL; iden++) { + for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSE_DW_REGS_END; iden++) { kvmppc_gsbm_set(&gsbm, iden); kvmppc_gsbm_set(&gsbm1, iden); KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden)); --- linux-xilinx-6.8.0.orig/arch/powerpc/lib/Makefile +++ linux-xilinx-6.8.0/arch/powerpc/lib/Makefile @@ -76,7 +76,7 @@ obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o obj-$(CONFIG_ALTIVEC) += xor_vmx.o xor_vmx_glue.o -CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec) +CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec) # Enable CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include) --- linux-xilinx-6.8.0.orig/arch/powerpc/lib/sstep.c +++ linux-xilinx-6.8.0/arch/powerpc/lib/sstep.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include --- linux-xilinx-6.8.0.orig/arch/powerpc/mm/book3s64/pgtable.c +++ linux-xilinx-6.8.0/arch/powerpc/mm/book3s64/pgtable.c @@ -130,7 +130,7 @@ WARN_ON(pte_hw_valid(pud_pte(*pudp))); assert_spin_locked(pud_lockptr(mm, pudp)); - WARN_ON(!(pud_large(pud))); + WARN_ON(!(pud_leaf(pud))); #endif trace_hugepage_set_pud(addr, pud_val(pud)); return set_pte_at(mm, addr, pudp_ptep(pudp), pud_pte(pud)); @@ -170,6 +170,7 @@ { unsigned long old_pmd; + VM_WARN_ON_ONCE(!pmd_present(*pmdp)); old_pmd = pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, _PAGE_INVALID); flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE); return __pmd(old_pmd); --- linux-xilinx-6.8.0.orig/arch/powerpc/mm/book3s64/radix_pgtable.c +++ linux-xilinx-6.8.0/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include @@ -293,7 +295,8 @@ static int __meminit create_physical_mapping(unsigned long start, unsigned long end, - int nid, pgprot_t _prot) + int nid, pgprot_t _prot, + unsigned long mapping_sz_limit) { unsigned long vaddr, addr, mapping_size = 0; bool prev_exec, exec = false; @@ -301,7 +304,10 @@ int psize; unsigned long max_mapping_size = memory_block_size; - if (debug_pagealloc_enabled_or_kfence()) + if (mapping_sz_limit < max_mapping_size) + max_mapping_size = mapping_sz_limit; + + if (debug_pagealloc_enabled()) max_mapping_size = PAGE_SIZE; start = ALIGN(start, PAGE_SIZE); @@ -356,8 +362,74 @@ return 0; } +#ifdef CONFIG_KFENCE +static bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL; + +static int __init parse_kfence_early_init(char *arg) +{ + int val; + + if (get_option(&arg, &val)) + kfence_early_init = !!val; + return 0; +} +early_param("kfence.sample_interval", parse_kfence_early_init); + +static inline phys_addr_t alloc_kfence_pool(void) +{ + phys_addr_t kfence_pool; + + /* + * TODO: Support to enable KFENCE after bootup depends on the ability to + * split page table mappings. As such support is not currently + * implemented for radix pagetables, support enabling KFENCE + * only at system startup for now. + * + * After support for splitting mappings is available on radix, + * alloc_kfence_pool() & map_kfence_pool() can be dropped and + * mapping for __kfence_pool memory can be + * split during arch_kfence_init_pool(). + */ + if (!kfence_early_init) + goto no_kfence; + + kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE); + if (!kfence_pool) + goto no_kfence; + + memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE); + return kfence_pool; + +no_kfence: + disable_kfence(); + return 0; +} + +static inline void map_kfence_pool(phys_addr_t kfence_pool) +{ + if (!kfence_pool) + return; + + if (create_physical_mapping(kfence_pool, kfence_pool + KFENCE_POOL_SIZE, + -1, PAGE_KERNEL, PAGE_SIZE)) + goto err; + + memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE); + __kfence_pool = __va(kfence_pool); + return; + +err: + memblock_phys_free(kfence_pool, KFENCE_POOL_SIZE); + disable_kfence(); +} +#else +static inline phys_addr_t alloc_kfence_pool(void) { return 0; } +static inline void map_kfence_pool(phys_addr_t kfence_pool) { } +#endif + static void __init radix_init_pgtable(void) { + phys_addr_t kfence_pool; unsigned long rts_field; phys_addr_t start, end; u64 i; @@ -365,6 +437,8 @@ /* We don't support slb for radix */ slb_set_size(0); + kfence_pool = alloc_kfence_pool(); + /* * Create the linear mapping */ @@ -381,9 +455,11 @@ } WARN_ON(create_physical_mapping(start, end, - -1, PAGE_KERNEL)); + -1, PAGE_KERNEL, ~0UL)); } + map_kfence_pool(kfence_pool); + if (!cpu_has_feature(CPU_FTR_HVMODE) && cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) { /* @@ -875,7 +951,7 @@ } return create_physical_mapping(__pa(start), __pa(end), - nid, prot); + nid, prot, ~0UL); } int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end) --- linux-xilinx-6.8.0.orig/arch/powerpc/mm/init-common.c +++ linux-xilinx-6.8.0/arch/powerpc/mm/init-common.c @@ -31,6 +31,9 @@ bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP); bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP); +#ifdef CONFIG_KFENCE +bool __ro_after_init kfence_disabled; +#endif static int __init parse_nosmep(char *p) { --- linux-xilinx-6.8.0.orig/arch/powerpc/net/bpf_jit_comp32.c +++ linux-xilinx-6.8.0/arch/powerpc/net/bpf_jit_comp32.c @@ -450,10 +450,16 @@ } break; case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */ - EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg)); + if (off) + EMIT(PPC_RAW_DIVW(dst_reg, src2_reg, src_reg)); + else + EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg)); break; case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */ - EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg)); + if (off) + EMIT(PPC_RAW_DIVW(_R0, src2_reg, src_reg)); + else + EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg)); EMIT(PPC_RAW_MULW(_R0, src_reg, _R0)); EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0)); break; @@ -467,10 +473,16 @@ if (imm == 1) { EMIT(PPC_RAW_MR(dst_reg, src2_reg)); } else if (is_power_of_2((u32)imm)) { - EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm))); + if (off) + EMIT(PPC_RAW_SRAWI(dst_reg, src2_reg, ilog2(imm))); + else + EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm))); } else { PPC_LI32(_R0, imm); - EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0)); + if (off) + EMIT(PPC_RAW_DIVW(dst_reg, src2_reg, _R0)); + else + EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0)); } break; case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */ @@ -480,11 +492,19 @@ if (!is_power_of_2((u32)imm)) { bpf_set_seen_register(ctx, tmp_reg); PPC_LI32(tmp_reg, imm); - EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg)); + if (off) + EMIT(PPC_RAW_DIVW(_R0, src2_reg, tmp_reg)); + else + EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg)); EMIT(PPC_RAW_MULW(_R0, tmp_reg, _R0)); EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0)); } else if (imm == 1) { EMIT(PPC_RAW_LI(dst_reg, 0)); + } else if (off) { + EMIT(PPC_RAW_SRAWI(_R0, src2_reg, ilog2(imm))); + EMIT(PPC_RAW_ADDZE(_R0, _R0)); + EMIT(PPC_RAW_SLWI(_R0, _R0, ilog2(imm))); + EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0)); } else { imm = ilog2((u32)imm); EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - imm, 31)); @@ -497,11 +517,21 @@ imm = -imm; if (!is_power_of_2(imm)) return -EOPNOTSUPP; - if (imm == 1) + if (imm == 1) { EMIT(PPC_RAW_LI(dst_reg, 0)); - else + EMIT(PPC_RAW_LI(dst_reg_h, 0)); + } else if (off) { + EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, 31)); + EMIT(PPC_RAW_XOR(dst_reg, src2_reg, dst_reg_h)); + EMIT(PPC_RAW_SUBFC(dst_reg, dst_reg_h, dst_reg)); + EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 32 - ilog2(imm), 31)); + EMIT(PPC_RAW_XOR(dst_reg, dst_reg, dst_reg_h)); + EMIT(PPC_RAW_SUBFC(dst_reg, dst_reg_h, dst_reg)); + EMIT(PPC_RAW_SUBFE(dst_reg_h, dst_reg_h, dst_reg_h)); + } else { EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - ilog2(imm), 31)); - EMIT(PPC_RAW_LI(dst_reg_h, 0)); + EMIT(PPC_RAW_LI(dst_reg_h, 0)); + } break; case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */ if (!imm) @@ -727,15 +757,30 @@ * MOV */ case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ - if (dst_reg == src_reg) - break; - EMIT(PPC_RAW_MR(dst_reg, src_reg)); - EMIT(PPC_RAW_MR(dst_reg_h, src_reg_h)); + if (off == 8) { + EMIT(PPC_RAW_EXTSB(dst_reg, src_reg)); + EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31)); + } else if (off == 16) { + EMIT(PPC_RAW_EXTSH(dst_reg, src_reg)); + EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31)); + } else if (off == 32 && dst_reg == src_reg) { + EMIT(PPC_RAW_SRAWI(dst_reg_h, src_reg, 31)); + } else if (off == 32) { + EMIT(PPC_RAW_MR(dst_reg, src_reg)); + EMIT(PPC_RAW_SRAWI(dst_reg_h, src_reg, 31)); + } else if (dst_reg != src_reg) { + EMIT(PPC_RAW_MR(dst_reg, src_reg)); + EMIT(PPC_RAW_MR(dst_reg_h, src_reg_h)); + } break; case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */ /* special mov32 for zext */ if (imm == 1) EMIT(PPC_RAW_LI(dst_reg_h, 0)); + else if (off == 8) + EMIT(PPC_RAW_EXTSB(dst_reg, src_reg)); + else if (off == 16) + EMIT(PPC_RAW_EXTSH(dst_reg, src_reg)); else if (dst_reg != src_reg) EMIT(PPC_RAW_MR(dst_reg, src_reg)); break; @@ -751,6 +796,7 @@ * BPF_FROM_BE/LE */ case BPF_ALU | BPF_END | BPF_FROM_LE: + case BPF_ALU64 | BPF_END | BPF_FROM_LE: switch (imm) { case 16: /* Copy 16 bits to upper part */ @@ -785,6 +831,8 @@ EMIT(PPC_RAW_MR(dst_reg_h, tmp_reg)); break; } + if (BPF_CLASS(code) == BPF_ALU64 && imm != 64) + EMIT(PPC_RAW_LI(dst_reg_h, 0)); break; case BPF_ALU | BPF_END | BPF_FROM_BE: switch (imm) { @@ -852,6 +900,15 @@ /* Get offset into TMP_REG */ EMIT(PPC_RAW_LI(tmp_reg, off)); + /* + * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync' + * before and after the operation. + * + * This is a requirement in the Linux Kernel Memory Model. + * See __cmpxchg_u32() in asm/cmpxchg.h as an example. + */ + if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP)) + EMIT(PPC_RAW_SYNC()); tmp_idx = ctx->idx * 4; /* load value from memory into r0 */ EMIT(PPC_RAW_LWARX(_R0, tmp_reg, dst_reg, 0)); @@ -905,6 +962,9 @@ /* For the BPF_FETCH variant, get old data into src_reg */ if (imm & BPF_FETCH) { + /* Emit 'sync' to enforce full ordering */ + if (IS_ENABLED(CONFIG_SMP)) + EMIT(PPC_RAW_SYNC()); EMIT(PPC_RAW_MR(ret_reg, ax_reg)); if (!fp->aux->verifier_zext) EMIT(PPC_RAW_LI(ret_reg - 1, 0)); /* higher 32-bit */ @@ -918,11 +978,17 @@ * BPF_LDX */ case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */ + case BPF_LDX | BPF_MEMSX | BPF_B: case BPF_LDX | BPF_PROBE_MEM | BPF_B: + case BPF_LDX | BPF_PROBE_MEMSX | BPF_B: case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */ + case BPF_LDX | BPF_MEMSX | BPF_H: case BPF_LDX | BPF_PROBE_MEM | BPF_H: + case BPF_LDX | BPF_PROBE_MEMSX | BPF_H: case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */ + case BPF_LDX | BPF_MEMSX | BPF_W: case BPF_LDX | BPF_PROBE_MEM | BPF_W: + case BPF_LDX | BPF_PROBE_MEMSX | BPF_W: case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */ case BPF_LDX | BPF_PROBE_MEM | BPF_DW: /* @@ -931,7 +997,7 @@ * load only if addr is kernel address (see is_kernel_addr()), otherwise * set dst_reg=0 and move on. */ - if (BPF_MODE(code) == BPF_PROBE_MEM) { + if (BPF_MODE(code) == BPF_PROBE_MEM || BPF_MODE(code) == BPF_PROBE_MEMSX) { PPC_LI32(_R0, TASK_SIZE - off); EMIT(PPC_RAW_CMPLW(src_reg, _R0)); PPC_BCC_SHORT(COND_GT, (ctx->idx + 4) * 4); @@ -953,30 +1019,48 @@ * as there are two load instructions for dst_reg_h & dst_reg * respectively. */ - if (size == BPF_DW) + if (size == BPF_DW || + (size == BPF_B && BPF_MODE(code) == BPF_PROBE_MEMSX)) PPC_JMP((ctx->idx + 3) * 4); else PPC_JMP((ctx->idx + 2) * 4); } - switch (size) { - case BPF_B: - EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off)); - break; - case BPF_H: - EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off)); - break; - case BPF_W: - EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off)); - break; - case BPF_DW: - EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off)); - EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4)); - break; - } + if (BPF_MODE(code) == BPF_MEMSX || BPF_MODE(code) == BPF_PROBE_MEMSX) { + switch (size) { + case BPF_B: + EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off)); + EMIT(PPC_RAW_EXTSB(dst_reg, dst_reg)); + break; + case BPF_H: + EMIT(PPC_RAW_LHA(dst_reg, src_reg, off)); + break; + case BPF_W: + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off)); + break; + } + if (!fp->aux->verifier_zext) + EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31)); - if (size != BPF_DW && !fp->aux->verifier_zext) - EMIT(PPC_RAW_LI(dst_reg_h, 0)); + } else { + switch (size) { + case BPF_B: + EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off)); + break; + case BPF_H: + EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off)); + break; + case BPF_W: + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off)); + break; + case BPF_DW: + EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off)); + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4)); + break; + } + if (size != BPF_DW && !fp->aux->verifier_zext) + EMIT(PPC_RAW_LI(dst_reg_h, 0)); + } if (BPF_MODE(code) == BPF_PROBE_MEM) { int insn_idx = ctx->idx - 1; @@ -1068,6 +1152,9 @@ case BPF_JMP | BPF_JA: PPC_JMP(addrs[i + 1 + off]); break; + case BPF_JMP32 | BPF_JA: + PPC_JMP(addrs[i + 1 + imm]); + break; case BPF_JMP | BPF_JGT | BPF_K: case BPF_JMP | BPF_JGT | BPF_X: --- linux-xilinx-6.8.0.orig/arch/powerpc/net/bpf_jit_comp64.c +++ linux-xilinx-6.8.0/arch/powerpc/net/bpf_jit_comp64.c @@ -202,7 +202,8 @@ EMIT(PPC_RAW_BLR()); } -static int bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx, u64 func) +static int +bpf_jit_emit_func_call_hlp(u32 *image, u32 *fimage, struct codegen_context *ctx, u64 func) { unsigned long func_addr = func ? ppc_function_entry((void *)func) : 0; long reladdr; @@ -211,19 +212,20 @@ return -EINVAL; if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) { - reladdr = func_addr - CTX_NIA(ctx); + reladdr = func_addr - local_paca->kernelbase; if (reladdr >= (long)SZ_8G || reladdr < -(long)SZ_8G) { - pr_err("eBPF: address of %ps out of range of pcrel address.\n", - (void *)func); + pr_err("eBPF: address of %ps out of range of 34-bit relative address.\n", + (void *)func); return -ERANGE; } - /* pla r12,addr */ - EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(1) | IMM_H18(reladdr)); - EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | IMM_L(reladdr)); - EMIT(PPC_RAW_MTCTR(_R12)); - EMIT(PPC_RAW_BCTR()); - + EMIT(PPC_RAW_LD(_R12, _R13, offsetof(struct paca_struct, kernelbase))); + /* Align for subsequent prefix instruction */ + if (!IS_ALIGNED((unsigned long)fimage + CTX_NIA(ctx), 8)) + EMIT(PPC_RAW_NOP()); + /* paddi r12,r12,addr */ + EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(0) | IMM_H18(reladdr)); + EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | ___PPC_RA(_R12) | IMM_L(reladdr)); } else { reladdr = func_addr - kernel_toc_addr(); if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { @@ -233,9 +235,9 @@ EMIT(PPC_RAW_ADDIS(_R12, _R2, PPC_HA(reladdr))); EMIT(PPC_RAW_ADDI(_R12, _R12, PPC_LO(reladdr))); - EMIT(PPC_RAW_MTCTR(_R12)); - EMIT(PPC_RAW_BCTRL()); } + EMIT(PPC_RAW_MTCTR(_R12)); + EMIT(PPC_RAW_BCTRL()); return 0; } @@ -285,7 +287,7 @@ int b2p_index = bpf_to_ppc(BPF_REG_3); int bpf_tailcall_prologue_size = 8; - if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2)) + if (!IS_ENABLED(CONFIG_PPC_KERNEL_PCREL) && IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2)) bpf_tailcall_prologue_size += 4; /* skip past the toc load */ /* @@ -803,6 +805,15 @@ /* Get offset into TMP_REG_1 */ EMIT(PPC_RAW_LI(tmp1_reg, off)); + /* + * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync' + * before and after the operation. + * + * This is a requirement in the Linux Kernel Memory Model. + * See __cmpxchg_u64() in asm/cmpxchg.h as an example. + */ + if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP)) + EMIT(PPC_RAW_SYNC()); tmp_idx = ctx->idx * 4; /* load value from memory into TMP_REG_2 */ if (size == BPF_DW) @@ -865,6 +876,9 @@ PPC_BCC_SHORT(COND_NE, tmp_idx); if (imm & BPF_FETCH) { + /* Emit 'sync' to enforce full ordering */ + if (IS_ENABLED(CONFIG_SMP)) + EMIT(PPC_RAW_SYNC()); EMIT(PPC_RAW_MR(ret_reg, _R0)); /* * Skip unnecessary zero-extension for 32-bit cmpxchg. @@ -993,7 +1007,7 @@ return ret; if (func_addr_fixed) - ret = bpf_jit_emit_func_call_hlp(image, ctx, func_addr); + ret = bpf_jit_emit_func_call_hlp(image, fimage, ctx, func_addr); else ret = bpf_jit_emit_func_call_rel(image, fimage, ctx, func_addr); --- linux-xilinx-6.8.0.orig/arch/powerpc/perf/hv-gpci.c +++ linux-xilinx-6.8.0/arch/powerpc/perf/hv-gpci.c @@ -695,6 +695,20 @@ ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); + + /* + * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL', + * specifies that the current buffer size cannot accommodate + * all the information and a partial buffer returned. + * Since in this function we are only accessing data for a given starting index, + * we don't need to accommodate whole data and can get required count by + * accessing first entry data. + * Hence hcall fails only incase the ret value is other than H_SUCCESS or + * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B). + */ + if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B) + ret = 0; + if (ret) { pr_devel("hcall failed: 0x%lx\n", ret); goto out; @@ -759,6 +773,7 @@ { u64 count; u8 length; + unsigned long ret; /* Not our event */ if (event->attr.type != event->pmu->type) @@ -789,13 +804,23 @@ } /* check if the request works... */ - if (single_gpci_request(event_get_request(event), + ret = single_gpci_request(event_get_request(event), event_get_starting_index(event), event_get_secondary_index(event), event_get_counter_info_version(event), event_get_offset(event), length, - &count)) { + &count); + + /* + * ret value as H_AUTHORITY implies that partition is not permitted to retrieve + * performance information, and required to set + * "Enable Performance Information Collection" option. + */ + if (ret == H_AUTHORITY) + return -EPERM; + + if (ret) { pr_devel("gpci hcall failed\n"); return -EINVAL; } --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/44x/warp.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/44x/warp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/85xx/smp.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/85xx/smp.c @@ -398,6 +398,7 @@ hard_irq_disable(); mpic_teardown_this_cpu(secondary); +#ifdef CONFIG_CRASH_DUMP if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) { /* * We enter the crash kernel on whatever cpu crashed, @@ -406,9 +407,11 @@ */ disable_threadbit = 1; disable_cpu = cpu_first_thread_sibling(cpu); - } else if (sibling != crashing_cpu && - cpu_thread_in_core(cpu) == 0 && - cpu_thread_in_core(sibling) != 0) { + } else if (sibling == crashing_cpu) { + return; + } +#endif + if (cpu_thread_in_core(cpu) == 0 && cpu_thread_in_core(sibling) != 0) { disable_threadbit = 2; disable_cpu = sibling; } --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/embedded6xx/linkstation.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -99,9 +99,6 @@ mpic_init(mpic); } -extern void avr_uart_configure(void); -extern void avr_uart_send(const char); - static void __noreturn linkstation_restart(char *cmd) { local_irq_disable(); --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/embedded6xx/mpc10x.h +++ linux-xilinx-6.8.0/arch/powerpc/platforms/embedded6xx/mpc10x.h @@ -156,4 +156,7 @@ /* For MPC107 boards that use the built-in openpic */ void mpc10x_set_openpic(void); +void avr_uart_configure(void); +void avr_uart_send(const char c); + #endif /* __PPC_KERNEL_MPC10X_H */ --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/powermac/Kconfig +++ linux-xilinx-6.8.0/arch/powerpc/platforms/powermac/Kconfig @@ -2,7 +2,7 @@ config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_BOOK3S && CPU_BIG_ENDIAN - select ADB_CUDA if POWER_RESET && PPC32 + select ADB_CUDA if POWER_RESET && ADB select MPIC select FORCE_PCI select PPC_INDIRECT_PCI if PPC32 --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/ps3/Kconfig +++ linux-xilinx-6.8.0/arch/powerpc/platforms/ps3/Kconfig @@ -67,6 +67,7 @@ config PS3_PS3AV depends on PPC_PS3 tristate "PS3 AV settings driver" if PS3_ADVANCED + select VIDEO select PS3_VUART default y help --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/iommu.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/iommu.c @@ -786,8 +786,16 @@ * parent bus. During reboot, there will be ibm,dma-window property to * define DMA window. For kdump, there will at least be default window or DDW * or both. + * There is an exception to the above. In case the PE goes into frozen + * state, firmware may not provide ibm,dma-window property at the time + * of LPAR boot up. */ + if (!pdn) { + pr_debug(" no ibm,dma-window property !\n"); + return; + } + ppci = PCI_DN(pdn); pr_debug(" parent is %pOF, iommu_table: 0x%p\n", --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/kexec.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/kexec.c @@ -61,11 +61,3 @@ } else xics_kexec_teardown_cpu(secondary); } - -void pseries_machine_kexec(struct kimage *image) -{ - if (firmware_has_feature(FW_FEATURE_SET_MODE)) - pseries_disable_reloc_on_exc(); - - default_machine_kexec(image); -} --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/lpar.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/lpar.c @@ -1886,10 +1886,10 @@ * h_get_mpp * H_GET_MPP hcall returns info in 7 parms */ -int h_get_mpp(struct hvcall_mpp_data *mpp_data) +long h_get_mpp(struct hvcall_mpp_data *mpp_data) { - int rc; - unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + long rc; rc = plpar_hcall9(H_GET_MPP, retbuf); --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/lparcfg.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/lparcfg.c @@ -113,8 +113,8 @@ */ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data) { - unsigned long rc; - unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + long rc; rc = plpar_hcall9(H_GET_PPP, retbuf); @@ -193,7 +193,7 @@ struct hvcall_ppp_data ppp_data; struct device_node *root; const __be32 *perf_level; - int rc; + long rc; rc = h_get_ppp(&ppp_data); if (rc) @@ -357,8 +357,8 @@ static void read_lpar_name(struct seq_file *m) { - if (read_rtas_lpar_name(m) && read_dt_lpar_name(m)) - pr_err_once("Error can't get the LPAR name"); + if (read_rtas_lpar_name(m)) + read_dt_lpar_name(m); } #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/papr_platform_attributes.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/papr_platform_attributes.c @@ -101,10 +101,12 @@ esi_buf_size = ESI_HDR_SIZE + (CURR_MAX_ESI_ATTRS * max_esi_attrs); temp_buf = krealloc(buf, esi_buf_size, GFP_KERNEL); - if (temp_buf) + if (temp_buf) { buf = temp_buf; - else - return -ENOMEM; + } else { + ret = -ENOMEM; + goto out_buf; + } goto retry; } --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/plpks.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/plpks.c @@ -415,8 +415,7 @@ break; } - usleep_range(PLPKS_FLUSH_SLEEP, - PLPKS_FLUSH_SLEEP + PLPKS_FLUSH_SLEEP_RANGE); + fsleep(PLPKS_FLUSH_SLEEP); timeout = timeout + PLPKS_FLUSH_SLEEP; } while (timeout < PLPKS_MAX_TIMEOUT); @@ -464,9 +463,10 @@ continuetoken = retbuf[0]; if (pseries_status_to_err(rc) == -EBUSY) { - int delay_ms = get_longbusy_msecs(rc); - mdelay(delay_ms); - timeout += delay_ms; + int delay_us = get_longbusy_msecs(rc) * 1000; + + fsleep(delay_us); + timeout += delay_us; } rc = pseries_status_to_err(rc); } while (rc == -EBUSY && timeout < PLPKS_MAX_TIMEOUT); --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/pseries.h +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/pseries.h @@ -38,7 +38,6 @@ #endif extern void pseries_kexec_cpu_down(int crash_shutdown, int secondary); -void pseries_machine_kexec(struct kimage *image); extern void pSeries_final_fixup(void); --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/setup.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/setup.c @@ -343,8 +343,8 @@ { void (*ctor)(void *) = get_dtl_cache_ctor(); - dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES, - DISPATCH_LOG_BYTES, 0, ctor); + dtl_cache = kmem_cache_create_usercopy("dtl", DISPATCH_LOG_BYTES, + DISPATCH_LOG_BYTES, 0, 0, DISPATCH_LOG_BYTES, ctor); if (!dtl_cache) { pr_warn("Failed to create dispatch trace log buffer cache\n"); pr_warn("Stolen time statistics will be unreliable\n"); @@ -1153,7 +1153,6 @@ .machine_check_exception = pSeries_machine_check_exception, .machine_check_log_err = pSeries_machine_check_log_err, #ifdef CONFIG_KEXEC_CORE - .machine_kexec = pseries_machine_kexec, .kexec_cpu_down = pseries_kexec_cpu_down, #endif #ifdef CONFIG_MEMORY_HOTPLUG --- linux-xilinx-6.8.0.orig/arch/powerpc/platforms/pseries/vio.c +++ linux-xilinx-6.8.0/arch/powerpc/platforms/pseries/vio.c @@ -39,7 +39,6 @@ .name = "vio", .type = "", .dev.init_name = "vio", - .dev.bus = &vio_bus_type, }; #ifdef CONFIG_PPC_SMLPAR --- linux-xilinx-6.8.0.orig/arch/powerpc/sysdev/fsl_msi.c +++ linux-xilinx-6.8.0/arch/powerpc/sysdev/fsl_msi.c @@ -566,10 +566,12 @@ .msiir_offset = 0x38, }; +#ifdef CONFIG_EPAPR_PARAVIRT static const struct fsl_msi_feature vmpic_msi_feature = { .fsl_pic_ip = FSL_PIC_IP_VMPIC, .msiir_offset = 0, }; +#endif static const struct of_device_id fsl_of_msi_ids[] = { { --- linux-xilinx-6.8.0.orig/arch/powerpc/xmon/xmon.c +++ linux-xilinx-6.8.0/arch/powerpc/xmon/xmon.c @@ -1352,7 +1352,7 @@ } termch = cpu; - if (!scanhex(&cpu)) { + if (!scanhex(&cpu) || cpu >= num_possible_cpus()) { /* print cpus waiting or in xmon */ printf("cpus stopped:"); last_cpu = first_cpu = NR_CPUS; @@ -2774,7 +2774,7 @@ termch = c; /* Put c back, it wasn't 'a' */ - if (scanhex(&num)) + if (scanhex(&num) && num < num_possible_cpus()) dump_one_paca(num); else dump_one_paca(xmon_owner); @@ -2847,7 +2847,7 @@ termch = c; /* Put c back, it wasn't 'a' */ - if (scanhex(&num)) + if (scanhex(&num) && num < num_possible_cpus()) dump_one_xive(num); else dump_one_xive(xmon_owner); --- linux-xilinx-6.8.0.orig/arch/riscv/Kconfig +++ linux-xilinx-6.8.0/arch/riscv/Kconfig @@ -37,7 +37,7 @@ select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL select ARCH_HAS_SYSCALL_WRAPPER select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_HAS_VDSO_DATA select ARCH_KEEP_MEMBLOCK if ACPI select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX @@ -96,7 +96,7 @@ select HAS_IOPORT if MMU select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP - select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT && !XIP_KERNEL + select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL select HAVE_ARCH_KASAN if MMU && 64BIT --- linux-xilinx-6.8.0.orig/arch/riscv/Kconfig.errata +++ linux-xilinx-6.8.0/arch/riscv/Kconfig.errata @@ -82,14 +82,14 @@ Otherwise, please say "N" here to avoid unnecessary overhead. -config ERRATA_THEAD_PBMT - bool "Apply T-Head memory type errata" +config ERRATA_THEAD_MAE + bool "Apply T-Head's memory attribute extension (XTheadMae) errata" depends on ERRATA_THEAD && 64BIT && MMU select RISCV_ALTERNATIVE_EARLY default y help - This will apply the memory type errata to handle the non-standard - memory type bits in page-table-entries on T-Head SoCs. + This will apply the memory attribute extension errata to handle the + non-standard PTE utilization on T-Head SoCs (XTheadMae). If you don't know what to do here, say "Y". --- linux-xilinx-6.8.0.orig/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts +++ linux-xilinx-6.8.0/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts @@ -160,9 +160,11 @@ status = "okay"; }; +/* UBUNTU: PCIe support is not yet ready, so disable it for now &pcie { status = "okay"; }; +*/ &qspi { status = "okay"; --- linux-xilinx-6.8.0.orig/arch/riscv/boot/dts/sifive/fu740-c000.dtsi +++ linux-xilinx-6.8.0/arch/riscv/boot/dts/sifive/fu740-c000.dtsi @@ -42,7 +42,7 @@ }; }; cpu1: cpu@1 { - compatible = "sifive,bullet0", "riscv"; + compatible = "sifive,u74-mc", "sifive,bullet0", "riscv"; d-cache-block-size = <64>; d-cache-sets = <64>; d-cache-size = <32768>; @@ -69,7 +69,7 @@ }; }; cpu2: cpu@2 { - compatible = "sifive,bullet0", "riscv"; + compatible = "sifive,u74-mc", "sifive,bullet0", "riscv"; d-cache-block-size = <64>; d-cache-sets = <64>; d-cache-size = <32768>; @@ -96,7 +96,7 @@ }; }; cpu3: cpu@3 { - compatible = "sifive,bullet0", "riscv"; + compatible = "sifive,u74-mc", "sifive,bullet0", "riscv"; d-cache-block-size = <64>; d-cache-sets = <64>; d-cache-size = <32768>; @@ -123,7 +123,7 @@ }; }; cpu4: cpu@4 { - compatible = "sifive,bullet0", "riscv"; + compatible = "sifive,u74-mc", "sifive,bullet0", "riscv"; d-cache-block-size = <64>; d-cache-sets = <64>; d-cache-size = <32768>; --- linux-xilinx-6.8.0.orig/arch/riscv/boot/dts/sifive/hifive-unleashed-a00-microsemi.dts +++ linux-xilinx-6.8.0/arch/riscv/boot/dts/sifive/hifive-unleashed-a00-microsemi.dts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +#include "hifive-unleashed-a00.dts" + +/ { + soc { + pcie: pcie@2030000000 { + #address-cells = <0x3>; + #interrupt-cells = <0x1>; + #size-cells = <0x2>; + compatible = "microsemi,ms-pf-axi-pcie-host"; + device_type = "pci"; + bus-range = <0x01 0x7f>; + interrupt-map = <0 0 0 1 &ms_pcie_intc 0 0 0 0 2 &ms_pcie_intc 1 0 0 0 3 &ms_pcie_intc 2 0 0 0 4 &ms_pcie_intc 3>; + interrupt-map-mask = <0 0 0 7>; + interrupt-parent = <&plic0>; + interrupts = <32>; + ranges = <0x3000000 0x0 0x40000000 0x0 0x40000000 0x0 0x20000000>; + reg = <0x20 0x30000000 0x0 0x4000000 0x20 0x0 0x0 0x100000>; + reg-names = "control", "apb"; + ms_pcie_intc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + }; + }; + }; +}; --- linux-xilinx-6.8.0.orig/arch/riscv/boot/dts/starfive/jh7100.dtsi +++ linux-xilinx-6.8.0/arch/riscv/boot/dts/starfive/jh7100.dtsi @@ -116,6 +116,7 @@ osc_sys: osc-sys { compatible = "fixed-clock"; #clock-cells = <0>; + clock-output-names = "osc_sys"; /* This value must be overridden by the board */ clock-frequency = <0>; }; @@ -123,6 +124,7 @@ osc_aud: osc-aud { compatible = "fixed-clock"; #clock-cells = <0>; + clock-output-names = "osc_aud"; /* This value must be overridden by the board */ clock-frequency = <0>; }; @@ -130,6 +132,7 @@ gmac_rmii_ref: gmac-rmii-ref { compatible = "fixed-clock"; #clock-cells = <0>; + clock-output-names = "gmac_rmii_ref"; /* Should be overridden by the board when needed */ clock-frequency = <0>; }; @@ -137,6 +140,7 @@ gmac_gr_mii_rxclk: gmac-gr-mii-rxclk { compatible = "fixed-clock"; #clock-cells = <0>; + clock-output-names = "gmac_gr_mii_rxclk"; /* Should be overridden by the board when needed */ clock-frequency = <0>; }; --- linux-xilinx-6.8.0.orig/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +++ linux-xilinx-6.8.0/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi @@ -189,7 +189,6 @@ axp15060: pmic@36 { compatible = "x-powers,axp15060"; reg = <0x36>; - interrupts = <0>; interrupt-controller; #interrupt-cells = <1>; @@ -230,24 +229,6 @@ status = "okay"; }; -&i2srx { - pinctrl-names = "default"; - pinctrl-0 = <&i2srx_pins>; - status = "okay"; -}; - -&i2stx0 { - pinctrl-names = "default"; - pinctrl-0 = <&mclk_ext_pins>; - status = "okay"; -}; - -&i2stx1 { - pinctrl-names = "default"; - pinctrl-0 = <&i2stx1_pins>; - status = "okay"; -}; - &mmc0 { max-frequency = <100000000>; assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>; @@ -392,46 +373,6 @@ }; }; - i2srx_pins: i2srx-0 { - clk-sd-pins { - pinmux = , - , - , - , - ; - input-enable; - }; - }; - - i2stx1_pins: i2stx1-0 { - sd-pins { - pinmux = ; - bias-disable; - input-disable; - }; - }; - - mclk_ext_pins: mclk-ext-0 { - mclk-ext-pins { - pinmux = ; - input-enable; - }; - }; - mmc0_pins: mmc0-0 { rst-pins { pinmux = ; - bias-pull-up; - drive-strength = <2>; - input-disable; - input-schmitt-disable; - slew-rate = <0>; - }; - - rx-pins { - pinmux = ; - input-enable; - }; - - sync-pins { - pinmux = ; - input-enable; - }; - - pcmclk-pins { - pinmux = ; - input-enable; - }; - }; - uart0_pins: uart0-0 { tx-pins { pinmux = ; - status = "okay"; -}; - &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins>; --- linux-xilinx-6.8.0.orig/arch/riscv/errata/thead/errata.c +++ linux-xilinx-6.8.0/arch/riscv/errata/thead/errata.c @@ -19,20 +19,26 @@ #include #include -static bool errata_probe_pbmt(unsigned int stage, - unsigned long arch_id, unsigned long impid) +#define CSR_TH_SXSTATUS 0x5c0 +#define SXSTATUS_MAEE _AC(0x200000, UL) + +static bool errata_probe_mae(unsigned int stage, + unsigned long arch_id, unsigned long impid) { - if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PBMT)) + if (!IS_ENABLED(CONFIG_ERRATA_THEAD_MAE)) return false; if (arch_id != 0 || impid != 0) return false; - if (stage == RISCV_ALTERNATIVES_EARLY_BOOT || - stage == RISCV_ALTERNATIVES_MODULE) - return true; + if (stage != RISCV_ALTERNATIVES_EARLY_BOOT && + stage != RISCV_ALTERNATIVES_MODULE) + return false; + + if (!(csr_read(CSR_TH_SXSTATUS) & SXSTATUS_MAEE)) + return false; - return false; + return true; } /* @@ -140,8 +146,8 @@ { u32 cpu_req_errata = 0; - if (errata_probe_pbmt(stage, archid, impid)) - cpu_req_errata |= BIT(ERRATA_THEAD_PBMT); + if (errata_probe_mae(stage, archid, impid)) + cpu_req_errata |= BIT(ERRATA_THEAD_MAE); errata_probe_cmo(stage, archid, impid); --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/errata_list.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/errata_list.h @@ -23,7 +23,7 @@ #endif #ifdef CONFIG_ERRATA_THEAD -#define ERRATA_THEAD_PBMT 0 +#define ERRATA_THEAD_MAE 0 #define ERRATA_THEAD_PMU 1 #define ERRATA_THEAD_NUMBER 2 #endif @@ -43,30 +43,40 @@ CONFIG_ERRATA_SIFIVE_CIP_453) #else /* !__ASSEMBLY__ */ -#define ALT_FLUSH_TLB_PAGE(x) \ +#define ALT_SFENCE_VMA_ASID(asid) \ +asm(ALTERNATIVE("sfence.vma x0, %0", "sfence.vma", SIFIVE_VENDOR_ID, \ + ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \ + : : "r" (asid) : "memory") + +#define ALT_SFENCE_VMA_ADDR(addr) \ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \ ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \ : : "r" (addr) : "memory") +#define ALT_SFENCE_VMA_ADDR_ASID(addr, asid) \ +asm(ALTERNATIVE("sfence.vma %0, %1", "sfence.vma", SIFIVE_VENDOR_ID, \ + ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200) \ + : : "r" (addr), "r" (asid) : "memory") + /* * _val is marked as "will be overwritten", so need to set it to 0 * in the default case. */ #define ALT_SVPBMT_SHIFT 61 -#define ALT_THEAD_PBMT_SHIFT 59 +#define ALT_THEAD_MAE_SHIFT 59 #define ALT_SVPBMT(_val, prot) \ asm(ALTERNATIVE_2("li %0, 0\t\nnop", \ "li %0, %1\t\nslli %0,%0,%3", 0, \ RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \ "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \ - ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \ + ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE) \ : "=r"(_val) \ : "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT), \ - "I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT), \ + "I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT), \ "I"(ALT_SVPBMT_SHIFT), \ - "I"(ALT_THEAD_PBMT_SHIFT)) + "I"(ALT_THEAD_MAE_SHIFT)) -#ifdef CONFIG_ERRATA_THEAD_PBMT +#ifdef CONFIG_ERRATA_THEAD_MAE /* * IO/NOCACHE memory types are handled together with svpbmt, * so on T-Head chips, check if no other memory type is set, @@ -83,11 +93,11 @@ "slli t3, t3, %3\n\t" \ "or %0, %0, t3\n\t" \ "2:", THEAD_VENDOR_ID, \ - ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \ + ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE) \ : "+r"(_val) \ - : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT), \ - "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT), \ - "I"(ALT_THEAD_PBMT_SHIFT) \ + : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT), \ + "I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT), \ + "I"(ALT_THEAD_MAE_SHIFT) \ : "t3") #else #define ALT_THEAD_PMA(_val) --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/insn.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/insn.h @@ -145,7 +145,7 @@ /* parts of opcode for RVF, RVD and RVQ */ #define RVFDQ_FL_FS_WIDTH_OFF 12 -#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(3, 0) +#define RVFDQ_FL_FS_WIDTH_MASK GENMASK(2, 0) #define RVFDQ_FL_FS_WIDTH_W 2 #define RVFDQ_FL_FS_WIDTH_D 3 #define RVFDQ_LS_FS_WIDTH_Q 4 --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/page.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/page.h @@ -89,7 +89,7 @@ #define PTE_FMT "%08lx" #endif -#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) && defined(CONFIG_MMU) /* * We override this value as its generic definition uses __pa too early in * the boot process (before kernel_map.va_pa_offset is set). --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/pgtable.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/pgtable.h @@ -439,9 +439,11 @@ return pte; } +#ifdef CONFIG_RISCV_ISA_SVNAPOT #define pte_leaf_size(pte) (pte_napot(pte) ? \ napot_cont_size(napot_cont_order(pte)) :\ PAGE_SIZE) +#endif #ifdef CONFIG_NUMA_BALANCING /* @@ -886,7 +888,7 @@ #define PAGE_SHARED __pgprot(0) #define PAGE_KERNEL __pgprot(0) #define swapper_pg_dir NULL -#define TASK_SIZE 0xffffffffUL +#define TASK_SIZE _AC(-1, UL) #define VMALLOC_START _AC(0, UL) #define VMALLOC_END TASK_SIZE --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/sbi.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/sbi.h @@ -370,6 +370,8 @@ static inline void sbi_init(void) {} #endif /* CONFIG_RISCV_SBI */ +unsigned long riscv_get_mvendorid(void); +unsigned long riscv_get_marchid(void); unsigned long riscv_cached_mvendorid(unsigned int cpu_id); unsigned long riscv_cached_marchid(unsigned int cpu_id); unsigned long riscv_cached_mimpid(unsigned int cpu_id); --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/tlbflush.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/tlbflush.h @@ -22,10 +22,27 @@ __asm__ __volatile__ ("sfence.vma" : : : "memory"); } +static inline void local_flush_tlb_all_asid(unsigned long asid) +{ + if (asid != FLUSH_TLB_NO_ASID) + ALT_SFENCE_VMA_ASID(asid); + else + local_flush_tlb_all(); +} + /* Flush one page from local TLB */ static inline void local_flush_tlb_page(unsigned long addr) { - ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory")); + ALT_SFENCE_VMA_ADDR(addr); +} + +static inline void local_flush_tlb_page_asid(unsigned long addr, + unsigned long asid) +{ + if (asid != FLUSH_TLB_NO_ASID) + ALT_SFENCE_VMA_ADDR_ASID(addr, asid); + else + local_flush_tlb_page(addr); } #else /* CONFIG_MMU */ #define local_flush_tlb_all() do { } while (0) --- linux-xilinx-6.8.0.orig/arch/riscv/include/asm/uaccess.h +++ linux-xilinx-6.8.0/arch/riscv/include/asm/uaccess.h @@ -319,7 +319,7 @@ #define __get_kernel_nofault(dst, src, type, err_label) \ do { \ - long __kr_err; \ + long __kr_err = 0; \ \ __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \ if (unlikely(__kr_err)) \ @@ -328,7 +328,7 @@ #define __put_kernel_nofault(dst, src, type, err_label) \ do { \ - long __kr_err; \ + long __kr_err = 0; \ \ __put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \ if (unlikely(__kr_err)) \ --- linux-xilinx-6.8.0.orig/arch/riscv/include/uapi/asm/auxvec.h +++ linux-xilinx-6.8.0/arch/riscv/include/uapi/asm/auxvec.h @@ -34,7 +34,7 @@ #define AT_L3_CACHEGEOMETRY 47 /* entries in ARCH_DLINFO */ -#define AT_VECTOR_SIZE_ARCH 9 +#define AT_VECTOR_SIZE_ARCH 10 #define AT_MINSIGSTKSZ 51 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */ --- linux-xilinx-6.8.0.orig/arch/riscv/include/uapi/asm/hwprobe.h +++ linux-xilinx-6.8.0/arch/riscv/include/uapi/asm/hwprobe.h @@ -54,7 +54,7 @@ #define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28) #define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29) #define RISCV_HWPROBE_EXT_ZVFH (1 << 30) -#define RISCV_HWPROBE_EXT_ZVFHMIN (1 << 31) +#define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31) #define RISCV_HWPROBE_EXT_ZFA (1ULL << 32) #define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33) #define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34) --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/cpu.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/cpu.c @@ -139,6 +139,34 @@ return -1; } +unsigned long __init riscv_get_marchid(void) +{ + struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); + +#if IS_ENABLED(CONFIG_RISCV_SBI) + ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid(); +#elif IS_ENABLED(CONFIG_RISCV_M_MODE) + ci->marchid = csr_read(CSR_MARCHID); +#else + ci->marchid = 0; +#endif + return ci->marchid; +} + +unsigned long __init riscv_get_mvendorid(void) +{ + struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); + +#if IS_ENABLED(CONFIG_RISCV_SBI) + ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid(); +#elif IS_ENABLED(CONFIG_RISCV_M_MODE) + ci->mvendorid = csr_read(CSR_MVENDORID); +#else + ci->mvendorid = 0; +#endif + return ci->mvendorid; +} + DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); unsigned long riscv_cached_mvendorid(unsigned int cpu_id) @@ -170,12 +198,16 @@ struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); #if IS_ENABLED(CONFIG_RISCV_SBI) - ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid(); - ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid(); + if (!ci->mvendorid) + ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid(); + if (!ci->marchid) + ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid(); ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid(); #elif IS_ENABLED(CONFIG_RISCV_M_MODE) - ci->mvendorid = csr_read(CSR_MVENDORID); - ci->marchid = csr_read(CSR_MARCHID); + if (!ci->mvendorid) + ci->mvendorid = csr_read(CSR_MVENDORID); + if (!ci->marchid) + ci->marchid = csr_read(CSR_MARCHID); ci->mimpid = csr_read(CSR_MIMPID); #else ci->mvendorid = 0; --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/cpu_ops_sbi.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/cpu_ops_sbi.c @@ -72,7 +72,7 @@ /* Make sure tidle is updated */ smp_mb(); bdata->task_ptr = tidle; - bdata->stack_ptr = task_stack_page(tidle) + THREAD_SIZE; + bdata->stack_ptr = task_pt_regs(tidle); /* Make sure boot data is updated */ smp_mb(); hsm_data = __pa(bdata); --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/cpu_ops_spinwait.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/cpu_ops_spinwait.c @@ -34,8 +34,7 @@ /* Make sure tidle is updated */ smp_mb(); - WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid], - task_stack_page(tidle) + THREAD_SIZE); + WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid], task_pt_regs(tidle)); WRITE_ONCE(__cpu_spinwait_task_pointer[hartid], tidle); } --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/cpufeature.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/cpufeature.c @@ -503,6 +503,8 @@ struct acpi_table_header *rhct; acpi_status status; unsigned int cpu; + u64 boot_vendorid; + u64 boot_archid; if (!acpi_disabled) { status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct); @@ -510,6 +512,9 @@ return; } + boot_vendorid = riscv_get_mvendorid(); + boot_archid = riscv_get_marchid(); + for_each_possible_cpu(cpu) { struct riscv_isainfo *isainfo = &hart_isa[cpu]; unsigned long this_hwcap = 0; @@ -557,8 +562,7 @@ * CPU cores with the ratified spec will contain non-zero * marchid. */ - if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID && - riscv_cached_marchid(cpu) == 0x0) { + if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) { this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v]; clear_bit(RISCV_ISA_EXT_v, isainfo->isa); } @@ -612,7 +616,7 @@ if (ext->subset_ext_size) { for (int j = 0; j < ext->subset_ext_size; j++) { - if (riscv_isa_extension_check(ext->subset_ext_ids[i])) + if (riscv_isa_extension_check(ext->subset_ext_ids[j])) set_bit(ext->subset_ext_ids[j], isainfo->isa); } } --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/machine_kexec.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/machine_kexec.c @@ -121,20 +121,12 @@ for_each_irq_desc(i, desc) { struct irq_chip *chip; - int ret; chip = irq_desc_get_chip(desc); if (!chip) continue; - /* - * First try to remove the active state. If this - * fails, try to EOI the interrupt. - */ - ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); - - if (ret && irqd_irq_inprogress(&desc->irq_data) && - chip->irq_eoi) + if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) chip->irq_eoi(&desc->irq_data); if (chip->irq_mask) --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/patch.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/patch.c @@ -80,6 +80,8 @@ */ lockdep_assert_held(&text_mutex); + preempt_disable(); + if (across_pages) patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1); @@ -92,6 +94,8 @@ if (across_pages) patch_unmap(FIX_TEXT_POKE1); + preempt_enable(); + return 0; } NOKPROBE_SYMBOL(__patch_insn_set); @@ -122,6 +126,8 @@ if (!riscv_patch_in_stop_machine) lockdep_assert_held(&text_mutex); + preempt_disable(); + if (across_pages) patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1); @@ -134,6 +140,8 @@ if (across_pages) patch_unmap(FIX_TEXT_POKE1); + preempt_enable(); + return ret; } NOKPROBE_SYMBOL(__patch_insn_write); --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/probes/ftrace.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/probes/ftrace.c @@ -11,6 +11,9 @@ struct kprobe_ctlblk *kcb; int bit; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/process.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/process.c @@ -27,8 +27,6 @@ #include #include -register unsigned long gp_in_global __asm__("gp"); - #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include unsigned long __stack_chk_guard __read_mostly; @@ -37,7 +35,7 @@ extern asmlinkage void ret_from_fork(void); -void arch_cpu_idle(void) +void noinstr arch_cpu_idle(void) { cpu_do_idle(); } @@ -207,7 +205,6 @@ if (unlikely(args->fn)) { /* Kernel thread */ memset(childregs, 0, sizeof(struct pt_regs)); - childregs->gp = gp_in_global; /* Supervisor/Machine, irqs on: */ childregs->status = SR_PP | SR_PIE; --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/signal.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/signal.c @@ -119,6 +119,13 @@ struct __sc_riscv_v_state __user *state = sc_vec; void __user *datap; + /* + * Mark the vstate as clean prior performing the actual copy, + * to avoid getting the vstate incorrectly clobbered by the + * discarded vector state. + */ + riscv_v_vstate_set_restore(current, regs); + /* Copy everything of __sc_riscv_v_state except datap. */ err = __copy_from_user(¤t->thread.vstate, &state->v_state, offsetof(struct __riscv_v_ext_state, datap)); @@ -133,13 +140,7 @@ * Copy the whole vector content from user space datap. Use * copy_from_user to prevent information leak. */ - err = copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize); - if (unlikely(err)) - return err; - - riscv_v_vstate_set_restore(current, regs); - - return err; + return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize); } #else #define save_v_state(task, regs) (0) --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/smpboot.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/smpboot.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -239,9 +239,10 @@ riscv_user_isa_enable(); /* - * Remote TLB flushes are ignored while the CPU is offline, so emit - * a local TLB flush right now just in case. + * Remote cache and TLB flushes are ignored while the CPU is offline, + * so flush them both right now just in case. */ + local_flush_icache_all(); local_flush_tlb_all(); complete(&cpu_running); /* --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/stacktrace.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/stacktrace.c @@ -18,10 +18,21 @@ extern asmlinkage void ret_from_exception(void); +static inline int fp_is_valid(unsigned long fp, unsigned long sp) +{ + unsigned long low, high; + + low = sp + sizeof(struct stackframe); + high = ALIGN(sp, THREAD_SIZE); + + return !(fp < low || fp > high || fp & 0x07); +} + void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *arg) { unsigned long fp, sp, pc; + int graph_idx = 0; int level = 0; if (regs) { @@ -41,26 +52,24 @@ } for (;;) { - unsigned long low, high; struct stackframe *frame; if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc)))) break; - /* Validate frame pointer */ - low = sp + sizeof(struct stackframe); - high = ALIGN(sp, THREAD_SIZE); - if (unlikely(fp < low || fp > high || fp & 0x7)) + if (unlikely(!fp_is_valid(fp, sp))) break; + /* Unwind stack frame */ frame = (struct stackframe *)fp - 1; sp = fp; - if (regs && (regs->epc == pc) && (frame->fp & 0x7)) { + if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) { + /* We hit function where ra is not saved on the stack */ fp = frame->ra; pc = regs->ra; } else { fp = frame->fp; - pc = ftrace_graph_ret_addr(current, NULL, frame->ra, + pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra, &frame->ra); if (pc == (unsigned long)ret_from_exception) { if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc))) @@ -148,7 +157,7 @@ return pc; } -noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, +noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, struct task_struct *task, struct pt_regs *regs) { walk_stackframe(task, regs, consume_entry, cookie); --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/traps.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/traps.c @@ -121,7 +121,7 @@ print_vma_addr(KERN_CONT " in ", instruction_pointer(regs)); pr_cont("\n"); __show_regs(regs); - dump_instr(KERN_EMERG, regs); + dump_instr(KERN_INFO, regs); } force_sig_fault(signo, code, (void __user *)addr); --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/traps_misaligned.c +++ linux-xilinx-6.8.0/arch/riscv/kernel/traps_misaligned.c @@ -632,7 +632,7 @@ * accesses emulated since tasks requesting such control can run on any * CPU. */ - for_each_present_cpu(cpu) { + for_each_online_cpu(cpu) { if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_EMULATED) { return; --- linux-xilinx-6.8.0.orig/arch/riscv/kernel/vdso/Makefile +++ linux-xilinx-6.8.0/arch/riscv/kernel/vdso/Makefile @@ -37,6 +37,7 @@ # Disable -pg to prevent insert call site CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS) +CFLAGS_REMOVE_hwprobe.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS) # Disable profiling and instrumentation for VDSO code GCOV_PROFILE := n --- linux-xilinx-6.8.0.orig/arch/riscv/kvm/aia_aplic.c +++ linux-xilinx-6.8.0/arch/riscv/kvm/aia_aplic.c @@ -137,11 +137,21 @@ raw_spin_lock_irqsave(&irqd->lock, flags); sm = irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK; - if (!pending && - ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) || - (sm == APLIC_SOURCECFG_SM_LEVEL_LOW))) + if (sm == APLIC_SOURCECFG_SM_INACTIVE) goto skip_write_pending; + if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH || + sm == APLIC_SOURCECFG_SM_LEVEL_LOW) { + if (!pending) + goto skip_write_pending; + if ((irqd->state & APLIC_IRQ_STATE_INPUT) && + sm == APLIC_SOURCECFG_SM_LEVEL_LOW) + goto skip_write_pending; + if (!(irqd->state & APLIC_IRQ_STATE_INPUT) && + sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) + goto skip_write_pending; + } + if (pending) irqd->state |= APLIC_IRQ_STATE_PENDING; else @@ -187,16 +197,31 @@ static bool aplic_read_input(struct aplic *aplic, u32 irq) { - bool ret; - unsigned long flags; + u32 sourcecfg, sm, raw_input, irq_inverted; struct aplic_irq *irqd; + unsigned long flags; + bool ret = false; if (!irq || aplic->nr_irqs <= irq) return false; irqd = &aplic->irqs[irq]; raw_spin_lock_irqsave(&irqd->lock, flags); - ret = (irqd->state & APLIC_IRQ_STATE_INPUT) ? true : false; + + sourcecfg = irqd->sourcecfg; + if (sourcecfg & APLIC_SOURCECFG_D) + goto skip; + + sm = sourcecfg & APLIC_SOURCECFG_SM_MASK; + if (sm == APLIC_SOURCECFG_SM_INACTIVE) + goto skip; + + raw_input = (irqd->state & APLIC_IRQ_STATE_INPUT) ? 1 : 0; + irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW || + sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0; + ret = !!(raw_input ^ irq_inverted); + +skip: raw_spin_unlock_irqrestore(&irqd->lock, flags); return ret; --- linux-xilinx-6.8.0.orig/arch/riscv/kvm/aia_device.c +++ linux-xilinx-6.8.0/arch/riscv/kvm/aia_device.c @@ -237,10 +237,11 @@ static u32 aia_imsic_hart_index(struct kvm_aia *aia, gpa_t addr) { - u32 hart, group = 0; + u32 hart = 0, group = 0; - hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) & - GENMASK_ULL(aia->nr_hart_bits - 1, 0); + if (aia->nr_hart_bits) + hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) & + GENMASK_ULL(aia->nr_hart_bits - 1, 0); if (aia->nr_group_bits) group = (addr >> aia->nr_group_shift) & GENMASK_ULL(aia->nr_group_bits - 1, 0); --- linux-xilinx-6.8.0.orig/arch/riscv/kvm/vcpu_insn.c +++ linux-xilinx-6.8.0/arch/riscv/kvm/vcpu_insn.c @@ -7,6 +7,8 @@ #include #include +#include + #define INSN_OPCODE_MASK 0x007c #define INSN_OPCODE_SHIFT 2 #define INSN_OPCODE_SYSTEM 28 @@ -213,9 +215,20 @@ unsigned long wr_mask); }; +static int seed_csr_rmw(struct kvm_vcpu *vcpu, unsigned int csr_num, + unsigned long *val, unsigned long new_val, + unsigned long wr_mask) +{ + if (!riscv_isa_extension_available(vcpu->arch.isa, ZKR)) + return KVM_INSN_ILLEGAL_TRAP; + + return KVM_INSN_EXIT_TO_USER_SPACE; +} + static const struct csr_func csr_funcs[] = { KVM_RISCV_VCPU_AIA_CSR_FUNCS KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS + { .base = CSR_SEED, .count = 1, .func = seed_csr_rmw }, }; /** --- linux-xilinx-6.8.0.orig/arch/riscv/kvm/vcpu_onereg.c +++ linux-xilinx-6.8.0/arch/riscv/kvm/vcpu_onereg.c @@ -714,9 +714,9 @@ switch (reg_subtype) { case KVM_REG_RISCV_ISA_SINGLE: return riscv_vcpu_set_isa_ext_single(vcpu, reg_num, reg_val); - case KVM_REG_RISCV_SBI_MULTI_EN: + case KVM_REG_RISCV_ISA_MULTI_EN: return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, true); - case KVM_REG_RISCV_SBI_MULTI_DIS: + case KVM_REG_RISCV_ISA_MULTI_DIS: return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false); default: return -ENOENT; --- linux-xilinx-6.8.0.orig/arch/riscv/kvm/vcpu_pmu.c +++ linux-xilinx-6.8.0/arch/riscv/kvm/vcpu_pmu.c @@ -39,7 +39,7 @@ u64 sample_period; if (!pmc->counter_val) - sample_period = counter_val_mask + 1; + sample_period = counter_val_mask; else sample_period = (-pmc->counter_val) & counter_val_mask; --- linux-xilinx-6.8.0.orig/arch/riscv/mm/init.c +++ linux-xilinx-6.8.0/arch/riscv/mm/init.c @@ -232,22 +232,23 @@ * In 64-bit, any use of __va/__pa before this point is wrong as we * did not know the start of DRAM before. */ - if (IS_ENABLED(CONFIG_64BIT)) + if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base; /* - * memblock allocator is not aware of the fact that last 4K bytes of - * the addressable memory can not be mapped because of IS_ERR_VALUE - * macro. Make sure that last 4k bytes are not usable by memblock - * if end of dram is equal to maximum addressable memory. For 64-bit - * kernel, this problem can't happen here as the end of the virtual - * address space is occupied by the kernel mapping then this check must - * be done as soon as the kernel mapping base address is determined. + * Reserve physical address space that would be mapped to virtual + * addresses greater than (void *)(-PAGE_SIZE) because: + * - This memory would overlap with ERR_PTR + * - This memory belongs to high memory, which is not supported + * + * This is not applicable to 64-bit kernel, because virtual addresses + * after (void *)(-PAGE_SIZE) are not linearly mapped: they are + * occupied by kernel mapping. Also it is unrealistic for high memory + * to exist on 64-bit platforms. */ if (!IS_ENABLED(CONFIG_64BIT)) { - max_mapped_addr = __pa(~(ulong)0); - if (max_mapped_addr == (phys_ram_end - 1)) - memblock_set_current_limit(max_mapped_addr - 4096); + max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE); + memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr); } min_low_pfn = PFN_UP(phys_ram_base); @@ -669,6 +670,9 @@ static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va, phys_addr_t size) { + if (debug_pagealloc_enabled()) + return PAGE_SIZE; + if (pgtable_l5_enabled && !(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE) return P4D_SIZE; @@ -824,6 +828,10 @@ disable_pgtable_l4(); } + /* UBUNTU: Force disable sv57 and fallback to sv48 */ + if (pgtable_l5_enabled) + disable_pgtable_l5(); + memset(early_pg_dir, 0, PAGE_SIZE); memset(early_p4d, 0, PAGE_SIZE); memset(early_pud, 0, PAGE_SIZE); --- linux-xilinx-6.8.0.orig/arch/riscv/mm/pageattr.c +++ linux-xilinx-6.8.0/arch/riscv/mm/pageattr.c @@ -387,17 +387,33 @@ } #ifdef CONFIG_DEBUG_PAGEALLOC +static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data) +{ + int enable = *(int *)data; + + unsigned long val = pte_val(ptep_get(pte)); + + if (enable) + val |= _PAGE_PRESENT; + else + val &= ~_PAGE_PRESENT; + + set_pte(pte, __pte(val)); + + return 0; +} + void __kernel_map_pages(struct page *page, int numpages, int enable) { if (!debug_pagealloc_enabled()) return; - if (enable) - __set_memory((unsigned long)page_address(page), numpages, - __pgprot(_PAGE_PRESENT), __pgprot(0)); - else - __set_memory((unsigned long)page_address(page), numpages, - __pgprot(0), __pgprot(_PAGE_PRESENT)); + unsigned long start = (unsigned long)page_address(page); + unsigned long size = PAGE_SIZE * numpages; + + apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable); + + flush_tlb_kernel_range(start, start + size); } #endif --- linux-xilinx-6.8.0.orig/arch/riscv/mm/tlbflush.c +++ linux-xilinx-6.8.0/arch/riscv/mm/tlbflush.c @@ -7,29 +7,6 @@ #include #include -static inline void local_flush_tlb_all_asid(unsigned long asid) -{ - if (asid != FLUSH_TLB_NO_ASID) - __asm__ __volatile__ ("sfence.vma x0, %0" - : - : "r" (asid) - : "memory"); - else - local_flush_tlb_all(); -} - -static inline void local_flush_tlb_page_asid(unsigned long addr, - unsigned long asid) -{ - if (asid != FLUSH_TLB_NO_ASID) - __asm__ __volatile__ ("sfence.vma %0, %1" - : - : "r" (addr), "r" (asid) - : "memory"); - else - local_flush_tlb_page(addr); -} - /* * Flush entire TLB if number of entries to be flushed is greater * than the threshold below. @@ -99,7 +76,7 @@ local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid); } -static void __flush_tlb_range(struct cpumask *cmask, unsigned long asid, +static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid, unsigned long start, unsigned long size, unsigned long stride) { @@ -200,7 +177,7 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) { - __flush_tlb_range((struct cpumask *)cpu_online_mask, FLUSH_TLB_NO_ASID, + __flush_tlb_range(cpu_online_mask, FLUSH_TLB_NO_ASID, start, end - start, PAGE_SIZE); } --- linux-xilinx-6.8.0.orig/arch/riscv/net/bpf_jit_comp64.c +++ linux-xilinx-6.8.0/arch/riscv/net/bpf_jit_comp64.c @@ -516,33 +516,33 @@ break; /* src_reg = atomic_fetch_(dst_reg + off16, src_reg) */ case BPF_ADD | BPF_FETCH: - emit(is64 ? rv_amoadd_d(rs, rs, rd, 0, 0) : - rv_amoadd_w(rs, rs, rd, 0, 0), ctx); + emit(is64 ? rv_amoadd_d(rs, rs, rd, 1, 1) : + rv_amoadd_w(rs, rs, rd, 1, 1), ctx); if (!is64) emit_zext_32(rs, ctx); break; case BPF_AND | BPF_FETCH: - emit(is64 ? rv_amoand_d(rs, rs, rd, 0, 0) : - rv_amoand_w(rs, rs, rd, 0, 0), ctx); + emit(is64 ? rv_amoand_d(rs, rs, rd, 1, 1) : + rv_amoand_w(rs, rs, rd, 1, 1), ctx); if (!is64) emit_zext_32(rs, ctx); break; case BPF_OR | BPF_FETCH: - emit(is64 ? rv_amoor_d(rs, rs, rd, 0, 0) : - rv_amoor_w(rs, rs, rd, 0, 0), ctx); + emit(is64 ? rv_amoor_d(rs, rs, rd, 1, 1) : + rv_amoor_w(rs, rs, rd, 1, 1), ctx); if (!is64) emit_zext_32(rs, ctx); break; case BPF_XOR | BPF_FETCH: - emit(is64 ? rv_amoxor_d(rs, rs, rd, 0, 0) : - rv_amoxor_w(rs, rs, rd, 0, 0), ctx); + emit(is64 ? rv_amoxor_d(rs, rs, rd, 1, 1) : + rv_amoxor_w(rs, rs, rd, 1, 1), ctx); if (!is64) emit_zext_32(rs, ctx); break; /* src_reg = atomic_xchg(dst_reg + off16, src_reg); */ case BPF_XCHG: - emit(is64 ? rv_amoswap_d(rs, rs, rd, 0, 0) : - rv_amoswap_w(rs, rs, rd, 0, 0), ctx); + emit(is64 ? rv_amoswap_d(rs, rs, rd, 1, 1) : + rv_amoswap_w(rs, rs, rd, 1, 1), ctx); if (!is64) emit_zext_32(rs, ctx); break; @@ -740,6 +740,9 @@ if (ret) return ret; + /* store prog start time */ + emit_mv(RV_REG_S1, RV_REG_A0, ctx); + /* if (__bpf_prog_enter(prog) == 0) * goto skip_exec_of_prog; */ @@ -747,9 +750,6 @@ /* nop reserved for conditional jump */ emit(rv_nop(), ctx); - /* store prog start time */ - emit_mv(RV_REG_S1, RV_REG_A0, ctx); - /* arg1: &args_off */ emit_addi(RV_REG_A0, RV_REG_FP, -args_off, ctx); if (!p->jited) --- linux-xilinx-6.8.0.orig/arch/s390/Kconfig +++ linux-xilinx-6.8.0/arch/s390/Kconfig @@ -82,7 +82,7 @@ select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYSCALL_WRAPPER - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_HAS_VDSO_DATA select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_INLINE_READ_LOCK @@ -113,6 +113,7 @@ select ARCH_INLINE_WRITE_UNLOCK_BH select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE + select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE select ARCH_STACKWALK select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_DEBUG_PAGEALLOC --- linux-xilinx-6.8.0.orig/arch/s390/boot/startup.c +++ linux-xilinx-6.8.0/arch/s390/boot/startup.c @@ -32,7 +32,6 @@ unsigned long __bootdata(ident_map_size); u64 __bootdata_preserved(stfle_fac_list[16]); -u64 __bootdata_preserved(alt_stfle_fac_list[16]); struct oldmem_data __bootdata_preserved(oldmem_data); struct machine_info machine; --- linux-xilinx-6.8.0.orig/arch/s390/boot/vmem.c +++ linux-xilinx-6.8.0/arch/s390/boot/vmem.c @@ -366,7 +366,7 @@ } pmd = boot_crst_alloc(_SEGMENT_ENTRY_EMPTY); pud_populate(&init_mm, pud, pmd); - } else if (pud_large(*pud)) { + } else if (pud_leaf(*pud)) { continue; } pgtable_pmd_populate(pud, addr, next, mode); --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/cpacf.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/cpacf.h @@ -166,28 +166,86 @@ typedef struct { unsigned char bytes[16]; } cpacf_mask_t; -/** - * cpacf_query() - check if a specific CPACF function is available - * @opcode: the opcode of the crypto instruction - * @func: the function code to test for - * - * Executes the query function for the given crypto instruction @opcode - * and checks if @func is available - * - * Returns 1 if @func is available for @opcode, 0 otherwise +/* + * Prototype for a not existing function to produce a link + * error if __cpacf_query() or __cpacf_check_opcode() is used + * with an invalid compile time const opcode. */ -static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask) +void __cpacf_bad_opcode(void); + +static __always_inline void __cpacf_query_rre(u32 opc, u8 r1, u8 r2, + cpacf_mask_t *mask) { asm volatile( - " lghi 0,0\n" /* query function */ - " lgr 1,%[mask]\n" - " spm 0\n" /* pckmo doesn't change the cc */ - /* Parameter regs are ignored, but must be nonzero and unique */ - "0: .insn rrf,%[opc] << 16,2,4,6,0\n" - " brc 1,0b\n" /* handle partial completion */ - : "=m" (*mask) - : [mask] "d" ((unsigned long)mask), [opc] "i" (opcode) - : "cc", "0", "1"); + " la %%r1,%[mask]\n" + " xgr %%r0,%%r0\n" + " .insn rre,%[opc] << 16,%[r1],%[r2]\n" + : [mask] "=R" (*mask) + : [opc] "i" (opc), + [r1] "i" (r1), [r2] "i" (r2) + : "cc", "r0", "r1"); +} + +static __always_inline void __cpacf_query_rrf(u32 opc, + u8 r1, u8 r2, u8 r3, u8 m4, + cpacf_mask_t *mask) +{ + asm volatile( + " la %%r1,%[mask]\n" + " xgr %%r0,%%r0\n" + " .insn rrf,%[opc] << 16,%[r1],%[r2],%[r3],%[m4]\n" + : [mask] "=R" (*mask) + : [opc] "i" (opc), [r1] "i" (r1), [r2] "i" (r2), + [r3] "i" (r3), [m4] "i" (m4) + : "cc", "r0", "r1"); +} + +static __always_inline void __cpacf_query(unsigned int opcode, + cpacf_mask_t *mask) +{ + switch (opcode) { + case CPACF_KDSA: + __cpacf_query_rre(CPACF_KDSA, 0, 2, mask); + break; + case CPACF_KIMD: + __cpacf_query_rre(CPACF_KIMD, 0, 2, mask); + break; + case CPACF_KLMD: + __cpacf_query_rre(CPACF_KLMD, 0, 2, mask); + break; + case CPACF_KM: + __cpacf_query_rre(CPACF_KM, 2, 4, mask); + break; + case CPACF_KMA: + __cpacf_query_rrf(CPACF_KMA, 2, 4, 6, 0, mask); + break; + case CPACF_KMAC: + __cpacf_query_rre(CPACF_KMAC, 0, 2, mask); + break; + case CPACF_KMC: + __cpacf_query_rre(CPACF_KMC, 2, 4, mask); + break; + case CPACF_KMCTR: + __cpacf_query_rrf(CPACF_KMCTR, 2, 4, 6, 0, mask); + break; + case CPACF_KMF: + __cpacf_query_rre(CPACF_KMF, 2, 4, mask); + break; + case CPACF_KMO: + __cpacf_query_rre(CPACF_KMO, 2, 4, mask); + break; + case CPACF_PCC: + __cpacf_query_rre(CPACF_PCC, 0, 0, mask); + break; + case CPACF_PCKMO: + __cpacf_query_rre(CPACF_PCKMO, 0, 0, mask); + break; + case CPACF_PRNO: + __cpacf_query_rre(CPACF_PRNO, 2, 4, mask); + break; + default: + __cpacf_bad_opcode(); + } } static __always_inline int __cpacf_check_opcode(unsigned int opcode) @@ -211,10 +269,21 @@ case CPACF_KMA: return test_facility(146); /* check for MSA8 */ default: - BUG(); + __cpacf_bad_opcode(); + return 0; } } +/** + * cpacf_query() - check if a specific CPACF function is available + * @opcode: the opcode of the crypto instruction + * @func: the function code to test for + * + * Executes the query function for the given crypto instruction @opcode + * and checks if @func is available + * + * Returns 1 if @func is available for @opcode, 0 otherwise + */ static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask) { if (__cpacf_check_opcode(opcode)) { --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/dwarf.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/dwarf.h @@ -9,6 +9,7 @@ #define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset #define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset #define CFI_RESTORE .cfi_restore +#define CFI_REL_OFFSET .cfi_rel_offset #ifdef CONFIG_AS_CFI_VAL_OFFSET #define CFI_VAL_OFFSET .cfi_val_offset --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/entry-common.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/entry-common.h @@ -55,7 +55,7 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, unsigned long ti_work) { - choose_random_kstack_offset(get_tod_clock_fast() & 0xff); + choose_random_kstack_offset(get_tod_clock_fast()); } #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/ftrace.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/ftrace.h @@ -8,12 +8,8 @@ #ifndef __ASSEMBLY__ -#ifdef CONFIG_CC_IS_CLANG -/* https://bugs.llvm.org/show_bug.cgi?id=41424 */ -#define ftrace_return_address(n) 0UL -#else -#define ftrace_return_address(n) __builtin_return_address(n) -#endif +unsigned long return_address(unsigned int n); +#define ftrace_return_address(n) return_address(n) void ftrace_caller(void); --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/gmap.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/gmap.h @@ -146,7 +146,7 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4], unsigned long gaddr, unsigned long vmaddr); -int gmap_mark_unmergeable(void); +int s390_disable_cow_sharing(void); void s390_unlist_old_asce(struct gmap *gmap); int s390_replace_asce(struct gmap *gmap); void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns); --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/ipl.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/ipl.h @@ -139,6 +139,7 @@ unsigned char flags, unsigned short cert); int ipl_report_add_certificate(struct ipl_report *report, void *key, unsigned long addr, unsigned long len); +bool ipl_get_secureboot(void); /* * DIAG 308 support --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/kvm_host.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/kvm_host.h @@ -427,6 +427,7 @@ u64 instruction_io_other; u64 instruction_lpsw; u64 instruction_lpswe; + u64 instruction_lpswey; u64 instruction_pfmf; u64 instruction_ptff; u64 instruction_sck; --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/mmu.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/mmu.h @@ -32,6 +32,11 @@ unsigned int uses_skeys:1; /* The mmu context uses CMM. */ unsigned int uses_cmm:1; + /* + * The mmu context allows COW-sharing of memory pages (KSM, zeropage). + * Note that COW-sharing during fork() is currently always allowed. + */ + unsigned int allow_cow_sharing:1; /* The gmaps associated with this context are allowed to use huge pages. */ unsigned int allow_gmap_hpage_1m:1; } mm_context_t; --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/mmu_context.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/mmu_context.h @@ -35,6 +35,7 @@ mm->context.has_pgste = 0; mm->context.uses_skeys = 0; mm->context.uses_cmm = 0; + mm->context.allow_cow_sharing = 1; mm->context.allow_gmap_hpage_1m = 0; #endif switch (mm->context.asce_limit) { --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/pgtable.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/pgtable.h @@ -566,10 +566,20 @@ } /* - * In the case that a guest uses storage keys - * faults should no longer be backed by zero pages + * As soon as the guest uses storage keys or enables PV, we deduplicate all + * mapped shared zeropages and prevent new shared zeropages from getting + * mapped. */ -#define mm_forbids_zeropage mm_has_pgste +#define mm_forbids_zeropage mm_forbids_zeropage +static inline int mm_forbids_zeropage(struct mm_struct *mm) +{ +#ifdef CONFIG_PGSTE + if (!mm->context.allow_cow_sharing) + return 1; +#endif + return 0; +} + static inline int mm_uses_skeys(struct mm_struct *mm) { #ifdef CONFIG_PGSTE @@ -730,7 +740,7 @@ { unsigned long type = pud_val(pud) & _REGION_ENTRY_TYPE_MASK; - if (type > _REGION_ENTRY_TYPE_R3 || pud_large(pud)) + if (type > _REGION_ENTRY_TYPE_R3 || pud_leaf(pud)) return 1; if (type < _REGION_ENTRY_TYPE_R3) return 0; @@ -1398,7 +1408,7 @@ unsigned long origin_mask; origin_mask = _REGION_ENTRY_ORIGIN; - if (pud_large(pud)) + if (pud_leaf(pud)) origin_mask = _REGION3_ENTRY_ORIGIN_LARGE; return (unsigned long)__va(pud_val(pud) & origin_mask); } @@ -1766,8 +1776,10 @@ static inline pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmdp) { - pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); + pmd_t pmd; + VM_WARN_ON_ONCE(!pmd_present(*pmdp)); + pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); return pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); } --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/processor.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/processor.h @@ -99,6 +99,7 @@ extern const struct seq_operations cpuinfo_op; extern void execve_tail(void); +unsigned long vdso_text_size(void); unsigned long vdso_size(void); /* @@ -303,8 +304,8 @@ */ static __always_inline void __load_psw_mask(unsigned long mask) { + psw_t psw __uninitialized; unsigned long addr; - psw_t psw; psw.mask = mask; --- linux-xilinx-6.8.0.orig/arch/s390/include/asm/stacktrace.h +++ linux-xilinx-6.8.0/arch/s390/include/asm/stacktrace.h @@ -2,6 +2,7 @@ #ifndef _ASM_S390_STACKTRACE_H #define _ASM_S390_STACKTRACE_H +#include #include #include #include @@ -13,6 +14,17 @@ unsigned long empty2[4]; }; +struct stack_frame_vdso_wrapper { + struct stack_frame_user sf; + unsigned long return_address; +}; + +struct perf_callchain_entry_ctx; + +void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie, + struct perf_callchain_entry_ctx *entry, + const struct pt_regs *regs, bool perf); + enum stack_type { STACK_TYPE_UNKNOWN, STACK_TYPE_TASK, --- linux-xilinx-6.8.0.orig/arch/s390/kernel/Makefile +++ linux-xilinx-6.8.0/arch/s390/kernel/Makefile @@ -11,6 +11,8 @@ # Do not trace early setup code CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_rethook.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_stacktrace.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_unwind_bc.o = $(CC_FLAGS_FTRACE) endif --- linux-xilinx-6.8.0.orig/arch/s390/kernel/asm-offsets.c +++ linux-xilinx-6.8.0/arch/s390/kernel/asm-offsets.c @@ -66,6 +66,11 @@ OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys); DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame)); BLANK(); + OFFSET(__SFUSER_BACKCHAIN, stack_frame_user, back_chain); + DEFINE(STACK_FRAME_USER_OVERHEAD, sizeof(struct stack_frame_user)); + OFFSET(__SFVDSO_RETURN_ADDRESS, stack_frame_vdso_wrapper, return_address); + DEFINE(STACK_FRAME_VDSO_OVERHEAD, sizeof(struct stack_frame_vdso_wrapper)); + BLANK(); /* idle data offsets */ OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter); OFFSET(__TIMER_IDLE_ENTER, s390_idle_data, timer_idle_enter); --- linux-xilinx-6.8.0.orig/arch/s390/kernel/cache.c +++ linux-xilinx-6.8.0/arch/s390/kernel/cache.c @@ -166,5 +166,6 @@ ci_leaf_init(this_leaf++, pvt, ctype, level, cpu); } } + this_cpu_ci->cpu_map_populated = true; return 0; } --- linux-xilinx-6.8.0.orig/arch/s390/kernel/entry.S +++ linux-xilinx-6.8.0/arch/s390/kernel/entry.S @@ -653,6 +653,7 @@ SYM_DATA_END(daton_psw) .section .rodata, "a" + .balign 8 #define SYSCALL(esame,emu) .quad __s390x_ ## esame SYM_DATA_START(sys_call_table) #include "asm/syscall_table.h" --- linux-xilinx-6.8.0.orig/arch/s390/kernel/ftrace.c +++ linux-xilinx-6.8.0/arch/s390/kernel/ftrace.c @@ -296,6 +296,9 @@ struct kprobe *p; int bit; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/s390/kernel/ipl.c +++ linux-xilinx-6.8.0/arch/s390/kernel/ipl.c @@ -962,8 +962,8 @@ scpdata_len += padding; } - reipl_block_nvme->hdr.len = IPL_BP_FCP_LEN + scpdata_len; - reipl_block_nvme->nvme.len = IPL_BP0_FCP_LEN + scpdata_len; + reipl_block_nvme->hdr.len = IPL_BP_NVME_LEN + scpdata_len; + reipl_block_nvme->nvme.len = IPL_BP0_NVME_LEN + scpdata_len; reipl_block_nvme->nvme.scp_data_len = scpdata_len; return count; @@ -1858,9 +1858,9 @@ } dump_block_nvme->hdr.len = IPL_BP_NVME_LEN; dump_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION; - dump_block_nvme->fcp.len = IPL_BP0_NVME_LEN; - dump_block_nvme->fcp.pbt = IPL_PBT_NVME; - dump_block_nvme->fcp.opt = IPL_PB0_NVME_OPT_DUMP; + dump_block_nvme->nvme.len = IPL_BP0_NVME_LEN; + dump_block_nvme->nvme.pbt = IPL_PBT_NVME; + dump_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_DUMP; dump_capabilities |= DUMP_TYPE_NVME; return 0; } @@ -2520,3 +2520,8 @@ } #endif + +bool ipl_get_secureboot(void) +{ + return !!ipl_secure_flag; +} --- linux-xilinx-6.8.0.orig/arch/s390/kernel/perf_cpum_cf.c +++ linux-xilinx-6.8.0/arch/s390/kernel/perf_cpum_cf.c @@ -428,7 +428,7 @@ case CPUMF_CTR_SET_CRYPTO: if (cpumf_ctr_info.csvn >= 1 && cpumf_ctr_info.csvn <= 5) ctrset_size = 16; - else if (cpumf_ctr_info.csvn == 6 || cpumf_ctr_info.csvn == 7) + else if (cpumf_ctr_info.csvn >= 6) ctrset_size = 20; break; case CPUMF_CTR_SET_EXT: --- linux-xilinx-6.8.0.orig/arch/s390/kernel/perf_cpum_cf_events.c +++ linux-xilinx-6.8.0/arch/s390/kernel/perf_cpum_cf_events.c @@ -855,16 +855,11 @@ } /* Determine version specific crypto set */ - switch (ci.csvn) { - case 1 ... 5: + csvn = none; + if (ci.csvn >= 1 && ci.csvn <= 5) csvn = cpumcf_svn_12345_pmu_event_attr; - break; - case 6 ... 7: + else if (ci.csvn >= 6) csvn = cpumcf_svn_67_pmu_event_attr; - break; - default: - csvn = none; - } /* Determine model-specific counter set(s) */ get_cpu_id(&cpu_id); --- linux-xilinx-6.8.0.orig/arch/s390/kernel/perf_event.c +++ linux-xilinx-6.8.0/arch/s390/kernel/perf_event.c @@ -218,39 +218,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { - struct stack_frame_user __user *sf; - unsigned long ip, sp; - bool first = true; - - if (is_compat_task()) - return; - perf_callchain_store(entry, instruction_pointer(regs)); - sf = (void __user *)user_stack_pointer(regs); - pagefault_disable(); - while (entry->nr < entry->max_stack) { - if (__get_user(sp, &sf->back_chain)) - break; - if (__get_user(ip, &sf->gprs[8])) - break; - if (ip & 0x1) { - /* - * If the instruction address is invalid, and this - * is the first stack frame, assume r14 has not - * been written to the stack yet. Otherwise exit. - */ - if (first && !(regs->gprs[14] & 0x1)) - ip = regs->gprs[14]; - else - break; - } - perf_callchain_store(entry, ip); - /* Sanity check: ABI requires SP to be aligned 8 bytes. */ - if (!sp || sp & 0x7) - break; - sf = (void __user *)sp; - first = false; - } - pagefault_enable(); + arch_stack_walk_user_common(NULL, NULL, entry, regs, true); } /* Perf definitions for PMU event attributes in sysfs */ --- linux-xilinx-6.8.0.orig/arch/s390/kernel/perf_pai_crypto.c +++ linux-xilinx-6.8.0/arch/s390/kernel/perf_pai_crypto.c @@ -90,7 +90,6 @@ event->cpu); struct paicrypt_map *cpump = mp->mapptr; - cpump->event = NULL; static_branch_dec(&pai_key); mutex_lock(&pai_reserve_mutex); debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d" @@ -348,10 +347,15 @@ static void paicrypt_stop(struct perf_event *event, int flags) { - if (!event->attr.sample_period) /* Counting */ + struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr); + struct paicrypt_map *cpump = mp->mapptr; + + if (!event->attr.sample_period) { /* Counting */ paicrypt_read(event); - else /* Sampling */ + } else { /* Sampling */ perf_sched_cb_dec(event->pmu); + cpump->event = NULL; + } event->hw.state = PERF_HES_STOPPED; } @@ -721,7 +725,7 @@ for (i = 0; i < ARRAY_SIZE(paicrypt_ctrnames); i++) { ret = attr_event_init_one(attrs, i); if (ret) { - attr_event_free(attrs, i - 1); + attr_event_free(attrs, i); return ret; } } --- linux-xilinx-6.8.0.orig/arch/s390/kernel/perf_pai_ext.c +++ linux-xilinx-6.8.0/arch/s390/kernel/perf_pai_ext.c @@ -121,7 +121,6 @@ struct paiext_map *cpump = mp->mapptr; mutex_lock(&paiext_reserve_mutex); - cpump->event = NULL; if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */ paiext_free(mp); paiext_root_free(); @@ -355,10 +354,15 @@ static void paiext_stop(struct perf_event *event, int flags) { - if (!event->attr.sample_period) /* Counting */ + struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr); + struct paiext_map *cpump = mp->mapptr; + + if (!event->attr.sample_period) { /* Counting */ paiext_read(event); - else /* Sampling */ + } else { /* Sampling */ perf_sched_cb_dec(event->pmu); + cpump->event = NULL; + } event->hw.state = PERF_HES_STOPPED; } @@ -611,7 +615,7 @@ for (i = 0; i < ARRAY_SIZE(paiext_ctrnames); i++) { ret = attr_event_init_one(attrs, i); if (ret) { - attr_event_free(attrs, i - 1); + attr_event_free(attrs, i); return ret; } } --- linux-xilinx-6.8.0.orig/arch/s390/kernel/setup.c +++ linux-xilinx-6.8.0/arch/s390/kernel/setup.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -155,7 +156,7 @@ EXPORT_SYMBOL(zlib_dfltcc_support); u64 __bootdata_preserved(stfle_fac_list[16]); EXPORT_SYMBOL(stfle_fac_list); -u64 __bootdata_preserved(alt_stfle_fac_list[16]); +u64 alt_stfle_fac_list[16]; struct oldmem_data __bootdata_preserved(oldmem_data); unsigned long VMALLOC_START; @@ -891,6 +892,9 @@ log_component_list(); + if (ipl_get_secureboot()) + security_lock_kernel_down("Secure IPL mode", LOCKDOWN_INTEGRITY_MAX); + /* Have one command line that is parsed and saved in /proc/cmdline */ /* boot_command_line has been already set up in early.c */ *cmdline_p = boot_command_line; --- linux-xilinx-6.8.0.orig/arch/s390/kernel/stacktrace.c +++ linux-xilinx-6.8.0/arch/s390/kernel/stacktrace.c @@ -5,6 +5,7 @@ * Copyright IBM Corp. 2006 */ +#include #include #include #include @@ -62,42 +63,121 @@ return 0; } -void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, - const struct pt_regs *regs) +static inline bool store_ip(stack_trace_consume_fn consume_entry, void *cookie, + struct perf_callchain_entry_ctx *entry, bool perf, + unsigned long ip) +{ +#ifdef CONFIG_PERF_EVENTS + if (perf) { + if (perf_callchain_store(entry, ip)) + return false; + return true; + } +#endif + return consume_entry(cookie, ip); +} + +static inline bool ip_invalid(unsigned long ip) +{ + /* + * Perform some basic checks if an instruction address taken + * from unreliable source is invalid. + */ + if (ip & 1) + return true; + if (ip < mmap_min_addr) + return true; + if (ip >= current->mm->context.asce_limit) + return true; + return false; +} + +static inline bool ip_within_vdso(unsigned long ip) { + return in_range(ip, current->mm->context.vdso_base, vdso_text_size()); +} + +void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie, + struct perf_callchain_entry_ctx *entry, + const struct pt_regs *regs, bool perf) +{ + struct stack_frame_vdso_wrapper __user *sf_vdso; struct stack_frame_user __user *sf; unsigned long ip, sp; bool first = true; if (is_compat_task()) return; - if (!consume_entry(cookie, instruction_pointer(regs))) + if (!current->mm) + return; + ip = instruction_pointer(regs); + if (!store_ip(consume_entry, cookie, entry, perf, ip)) return; sf = (void __user *)user_stack_pointer(regs); pagefault_disable(); while (1) { if (__get_user(sp, &sf->back_chain)) break; - if (__get_user(ip, &sf->gprs[8])) + /* + * VDSO entry code has a non-standard stack frame layout. + * See VDSO user wrapper code for details. + */ + if (!sp && ip_within_vdso(ip)) { + sf_vdso = (void __user *)sf; + if (__get_user(ip, &sf_vdso->return_address)) + break; + sp = (unsigned long)sf + STACK_FRAME_VDSO_OVERHEAD; + sf = (void __user *)sp; + if (__get_user(sp, &sf->back_chain)) + break; + } else { + sf = (void __user *)sp; + if (__get_user(ip, &sf->gprs[8])) + break; + } + /* Sanity check: ABI requires SP to be 8 byte aligned. */ + if (sp & 0x7) break; - if (ip & 0x1) { + if (ip_invalid(ip)) { /* * If the instruction address is invalid, and this * is the first stack frame, assume r14 has not * been written to the stack yet. Otherwise exit. */ - if (first && !(regs->gprs[14] & 0x1)) - ip = regs->gprs[14]; - else + if (!first) + break; + ip = regs->gprs[14]; + if (ip_invalid(ip)) break; } - if (!consume_entry(cookie, ip)) - break; - /* Sanity check: ABI requires SP to be aligned 8 bytes. */ - if (!sp || sp & 0x7) - break; - sf = (void __user *)sp; + if (!store_ip(consume_entry, cookie, entry, perf, ip)) + return; first = false; } pagefault_enable(); } + +void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie, + const struct pt_regs *regs) +{ + arch_stack_walk_user_common(consume_entry, cookie, NULL, regs, false); +} + +unsigned long return_address(unsigned int n) +{ + struct unwind_state state; + unsigned long addr; + + /* Increment to skip current stack entry */ + n++; + + unwind_for_each_frame(&state, NULL, NULL, 0) { + addr = unwind_get_return_address(&state); + if (!addr) + break; + if (!n--) + return addr; + } + return 0; +} +EXPORT_SYMBOL_GPL(return_address); --- linux-xilinx-6.8.0.orig/arch/s390/kernel/syscalls/syscall.tbl +++ linux-xilinx-6.8.0/arch/s390/kernel/syscalls/syscall.tbl @@ -418,7 +418,7 @@ 412 32 utimensat_time64 - sys_utimensat 413 32 pselect6_time64 - compat_sys_pselect6_time64 414 32 ppoll_time64 - compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 - sys_io_pgetevents +416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64 417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64 418 32 mq_timedsend_time64 - sys_mq_timedsend 419 32 mq_timedreceive_time64 - sys_mq_timedreceive --- linux-xilinx-6.8.0.orig/arch/s390/kernel/vdso.c +++ linux-xilinx-6.8.0/arch/s390/kernel/vdso.c @@ -213,17 +213,22 @@ return addr; } -unsigned long vdso_size(void) +unsigned long vdso_text_size(void) { - unsigned long size = VVAR_NR_PAGES * PAGE_SIZE; + unsigned long size; if (is_compat_task()) - size += vdso32_end - vdso32_start; + size = vdso32_end - vdso32_start; else - size += vdso64_end - vdso64_start; + size = vdso64_end - vdso64_start; return PAGE_ALIGN(size); } +unsigned long vdso_size(void) +{ + return vdso_text_size() + VVAR_NR_PAGES * PAGE_SIZE; +} + int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { unsigned long addr = VDSO_BASE; --- linux-xilinx-6.8.0.orig/arch/s390/kernel/vdso32/Makefile +++ linux-xilinx-6.8.0/arch/s390/kernel/vdso32/Makefile @@ -19,10 +19,12 @@ KBUILD_AFLAGS_32 += -m31 -s KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS)) +KBUILD_CFLAGS_32 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_32 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_32)) -KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin +KBUILD_CFLAGS_32 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_32)) +KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin -fasynchronous-unwind-tables -LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \ +LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \ --hash-style=both --build-id=sha1 -melf_s390 -T $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32) --- linux-xilinx-6.8.0.orig/arch/s390/kernel/vdso64/Makefile +++ linux-xilinx-6.8.0/arch/s390/kernel/vdso64/Makefile @@ -24,9 +24,12 @@ KBUILD_AFLAGS_64 += -m64 KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) +KBUILD_CFLAGS_64 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_64)) KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64)) -KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \ +KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64)) +KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64)) +KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables +ldflags-y := -shared -soname=linux-vdso64.so.1 \ --hash-style=both --build-id=sha1 -T $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) --- linux-xilinx-6.8.0.orig/arch/s390/kernel/vdso64/vdso_user_wrapper.S +++ linux-xilinx-6.8.0/arch/s390/kernel/vdso64/vdso_user_wrapper.S @@ -6,8 +6,6 @@ #include #include -#define WRAPPER_FRAME_SIZE (STACK_FRAME_OVERHEAD+8) - /* * Older glibc version called vdso without allocating a stackframe. This wrapper * is just used to allocate a stackframe. See @@ -20,14 +18,17 @@ __ALIGN __kernel_\func: CFI_STARTPROC - aghi %r15,-WRAPPER_FRAME_SIZE - CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE) - CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD - stg %r14,STACK_FRAME_OVERHEAD(%r15) + aghi %r15,-STACK_FRAME_VDSO_OVERHEAD + CFI_DEF_CFA_OFFSET (STACK_FRAME_USER_OVERHEAD + STACK_FRAME_VDSO_OVERHEAD) + CFI_VAL_OFFSET 15,-STACK_FRAME_USER_OVERHEAD + stg %r14,__SFVDSO_RETURN_ADDRESS(%r15) + CFI_REL_OFFSET 14,__SFVDSO_RETURN_ADDRESS + xc __SFUSER_BACKCHAIN(8,%r15),__SFUSER_BACKCHAIN(%r15) brasl %r14,__s390_vdso_\func - lg %r14,STACK_FRAME_OVERHEAD(%r15) - aghi %r15,WRAPPER_FRAME_SIZE - CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD + lg %r14,__SFVDSO_RETURN_ADDRESS(%r15) + CFI_RESTORE 14 + aghi %r15,STACK_FRAME_VDSO_OVERHEAD + CFI_DEF_CFA_OFFSET STACK_FRAME_USER_OVERHEAD CFI_RESTORE 15 br %r14 CFI_ENDPROC --- linux-xilinx-6.8.0.orig/arch/s390/kernel/vtime.c +++ linux-xilinx-6.8.0/arch/s390/kernel/vtime.c @@ -210,13 +210,13 @@ virt_timer_expire(); steal = S390_lowcore.steal_timer; - avg_steal = S390_lowcore.avg_steal_timer / 2; + avg_steal = S390_lowcore.avg_steal_timer; if ((s64) steal > 0) { S390_lowcore.steal_timer = 0; account_steal_time(cputime_to_nsecs(steal)); avg_steal += steal; } - S390_lowcore.avg_steal_timer = avg_steal; + S390_lowcore.avg_steal_timer = avg_steal / 2; } static u64 vtime_delta(void) --- linux-xilinx-6.8.0.orig/arch/s390/kvm/kvm-s390.c +++ linux-xilinx-6.8.0/arch/s390/kvm/kvm-s390.c @@ -132,6 +132,7 @@ STATS_DESC_COUNTER(VCPU, instruction_io_other), STATS_DESC_COUNTER(VCPU, instruction_lpsw), STATS_DESC_COUNTER(VCPU, instruction_lpswe), + STATS_DESC_COUNTER(VCPU, instruction_lpswey), STATS_DESC_COUNTER(VCPU, instruction_pfmf), STATS_DESC_COUNTER(VCPU, instruction_ptff), STATS_DESC_COUNTER(VCPU, instruction_sck), @@ -2631,9 +2632,7 @@ if (r) break; - mmap_write_lock(current->mm); - r = gmap_mark_unmergeable(); - mmap_write_unlock(current->mm); + r = s390_disable_cow_sharing(); if (r) break; --- linux-xilinx-6.8.0.orig/arch/s390/kvm/kvm-s390.h +++ linux-xilinx-6.8.0/arch/s390/kvm/kvm-s390.h @@ -120,6 +120,21 @@ return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2; } +static inline u64 kvm_s390_get_base_disp_siy(struct kvm_vcpu *vcpu, u8 *ar) +{ + u32 base1 = vcpu->arch.sie_block->ipb >> 28; + s64 disp1; + + /* The displacement is a 20bit _SIGNED_ value */ + disp1 = sign_extend64(((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) + + ((vcpu->arch.sie_block->ipb & 0xff00) << 4), 19); + + if (ar) + *ar = base1; + + return (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1; +} + static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu, u64 *address1, u64 *address2, u8 *ar_b1, u8 *ar_b2) --- linux-xilinx-6.8.0.orig/arch/s390/kvm/priv.c +++ linux-xilinx-6.8.0/arch/s390/kvm/priv.c @@ -797,6 +797,36 @@ return 0; } +static int handle_lpswey(struct kvm_vcpu *vcpu) +{ + psw_t new_psw; + u64 addr; + int rc; + u8 ar; + + vcpu->stat.instruction_lpswey++; + + if (!test_kvm_facility(vcpu->kvm, 193)) + return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); + + if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) + return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); + + addr = kvm_s390_get_base_disp_siy(vcpu, &ar); + if (addr & 7) + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); + + rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw)); + if (rc) + return kvm_s390_inject_prog_cond(vcpu, rc); + + vcpu->arch.sie_block->gpsw = new_psw; + if (!is_valid_psw(&vcpu->arch.sie_block->gpsw)) + return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); + + return 0; +} + static int handle_stidp(struct kvm_vcpu *vcpu) { u64 stidp_data = vcpu->kvm->arch.model.cpuid; @@ -1462,6 +1492,8 @@ case 0x61: case 0x62: return handle_ri(vcpu); + case 0x71: + return handle_lpswey(vcpu); default: return -EOPNOTSUPP; } --- linux-xilinx-6.8.0.orig/arch/s390/mm/fault.c +++ linux-xilinx-6.8.0/arch/s390/mm/fault.c @@ -430,12 +430,13 @@ handle_fault_error_nolock(regs, 0); else do_sigsegv(regs, SEGV_MAPERR); - } else if (fault & VM_FAULT_SIGBUS) { + } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) { if (!user_mode(regs)) handle_fault_error_nolock(regs, 0); else do_sigbus(regs); } else { + pr_emerg("Unexpected fault flags: %08x\n", fault); BUG(); } } --- linux-xilinx-6.8.0.orig/arch/s390/mm/gmap.c +++ linux-xilinx-6.8.0/arch/s390/mm/gmap.c @@ -596,7 +596,7 @@ pud = pud_offset(p4d, vmaddr); VM_BUG_ON(pud_none(*pud)); /* large puds cannot yet be handled */ - if (pud_large(*pud)) + if (pud_leaf(*pud)) return -EFAULT; pmd = pmd_offset(pud, vmaddr); VM_BUG_ON(pmd_none(*pmd)); @@ -2548,41 +2548,6 @@ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ /* - * Remove all empty zero pages from the mapping for lazy refaulting - * - This must be called after mm->context.has_pgste is set, to avoid - * future creation of zero pages - * - This must be called after THP was disabled. - * - * mm contracts with s390, that even if mm were to remove a page table, - * racing with the loop below and so causing pte_offset_map_lock() to fail, - * it will never insert a page table containing empty zero pages once - * mm_forbids_zeropage(mm) i.e. mm->context.has_pgste is set. - */ -static int __zap_zero_pages(pmd_t *pmd, unsigned long start, - unsigned long end, struct mm_walk *walk) -{ - unsigned long addr; - - for (addr = start; addr != end; addr += PAGE_SIZE) { - pte_t *ptep; - spinlock_t *ptl; - - ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); - if (!ptep) - break; - if (is_zero_pfn(pte_pfn(*ptep))) - ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID)); - pte_unmap_unlock(ptep, ptl); - } - return 0; -} - -static const struct mm_walk_ops zap_zero_walk_ops = { - .pmd_entry = __zap_zero_pages, - .walk_lock = PGWALK_WRLOCK, -}; - -/* * switch on pgstes for its userspace process (for kvm) */ int s390_enable_sie(void) @@ -2599,22 +2564,142 @@ mm->context.has_pgste = 1; /* split thp mappings and disable thp for future mappings */ thp_split_mm(mm); - walk_page_range(mm, 0, TASK_SIZE, &zap_zero_walk_ops, NULL); mmap_write_unlock(mm); return 0; } EXPORT_SYMBOL_GPL(s390_enable_sie); -int gmap_mark_unmergeable(void) +static int find_zeropage_pte_entry(pte_t *pte, unsigned long addr, + unsigned long end, struct mm_walk *walk) { + unsigned long *found_addr = walk->private; + + /* Return 1 of the page is a zeropage. */ + if (is_zero_pfn(pte_pfn(*pte))) { + /* + * Shared zeropage in e.g., a FS DAX mapping? We cannot do the + * right thing and likely don't care: FAULT_FLAG_UNSHARE + * currently only works in COW mappings, which is also where + * mm_forbids_zeropage() is checked. + */ + if (!is_cow_mapping(walk->vma->vm_flags)) + return -EFAULT; + + *found_addr = addr; + return 1; + } + return 0; +} + +static const struct mm_walk_ops find_zeropage_ops = { + .pte_entry = find_zeropage_pte_entry, + .walk_lock = PGWALK_WRLOCK, +}; + +/* + * Unshare all shared zeropages, replacing them by anonymous pages. Note that + * we cannot simply zap all shared zeropages, because this could later + * trigger unexpected userfaultfd missing events. + * + * This must be called after mm->context.allow_cow_sharing was + * set to 0, to avoid future mappings of shared zeropages. + * + * mm contracts with s390, that even if mm were to remove a page table, + * and racing with walk_page_range_vma() calling pte_offset_map_lock() + * would fail, it will never insert a page table containing empty zero + * pages once mm_forbids_zeropage(mm) i.e. + * mm->context.allow_cow_sharing is set to 0. + */ +static int __s390_unshare_zeropages(struct mm_struct *mm) +{ + struct vm_area_struct *vma; + VMA_ITERATOR(vmi, mm, 0); + unsigned long addr; + vm_fault_t fault; + int rc; + + for_each_vma(vmi, vma) { + /* + * We could only look at COW mappings, but it's more future + * proof to catch unexpected zeropages in other mappings and + * fail. + */ + if ((vma->vm_flags & VM_PFNMAP) || is_vm_hugetlb_page(vma)) + continue; + addr = vma->vm_start; + +retry: + rc = walk_page_range_vma(vma, addr, vma->vm_end, + &find_zeropage_ops, &addr); + if (rc < 0) + return rc; + else if (!rc) + continue; + + /* addr was updated by find_zeropage_pte_entry() */ + fault = handle_mm_fault(vma, addr, + FAULT_FLAG_UNSHARE | FAULT_FLAG_REMOTE, + NULL); + if (fault & VM_FAULT_OOM) + return -ENOMEM; + /* + * See break_ksm(): even after handle_mm_fault() returned 0, we + * must start the lookup from the current address, because + * handle_mm_fault() may back out if there's any difficulty. + * + * VM_FAULT_SIGBUS and VM_FAULT_SIGSEGV are unexpected but + * maybe they could trigger in the future on concurrent + * truncation. In that case, the shared zeropage would be gone + * and we can simply retry and make progress. + */ + cond_resched(); + goto retry; + } + + return 0; +} + +static int __s390_disable_cow_sharing(struct mm_struct *mm) +{ + int rc; + + if (!mm->context.allow_cow_sharing) + return 0; + + mm->context.allow_cow_sharing = 0; + + /* Replace all shared zeropages by anonymous pages. */ + rc = __s390_unshare_zeropages(mm); /* * Make sure to disable KSM (if enabled for the whole process or * individual VMAs). Note that nothing currently hinders user space * from re-enabling it. */ - return ksm_disable(current->mm); + if (!rc) + rc = ksm_disable(mm); + if (rc) + mm->context.allow_cow_sharing = 1; + return rc; +} + +/* + * Disable most COW-sharing of memory pages for the whole process: + * (1) Disable KSM and unmerge/unshare any KSM pages. + * (2) Disallow shared zeropages and unshare any zerpages that are mapped. + * + * Not that we currently don't bother with COW-shared pages that are shared + * with parent/child processes due to fork(). + */ +int s390_disable_cow_sharing(void) +{ + int rc; + + mmap_write_lock(current->mm); + rc = __s390_disable_cow_sharing(current->mm); + mmap_write_unlock(current->mm); + return rc; } -EXPORT_SYMBOL_GPL(gmap_mark_unmergeable); +EXPORT_SYMBOL_GPL(s390_disable_cow_sharing); /* * Enable storage key handling from now on and initialize the storage @@ -2659,7 +2744,7 @@ return 0; start = pmd_val(*pmd) & HPAGE_MASK; - end = start + HPAGE_SIZE - 1; + end = start + HPAGE_SIZE; __storage_key_init_range(start, end); set_bit(PG_arch_1, &page->flags); cond_resched(); @@ -2683,7 +2768,7 @@ goto out_up; mm->context.uses_skeys = 1; - rc = gmap_mark_unmergeable(); + rc = __s390_disable_cow_sharing(mm); if (rc) { mm->context.uses_skeys = 0; goto out_up; --- linux-xilinx-6.8.0.orig/arch/s390/mm/hugetlbpage.c +++ linux-xilinx-6.8.0/arch/s390/mm/hugetlbpage.c @@ -139,7 +139,7 @@ } if (!test_and_set_bit(PG_arch_1, &page->flags)) - __storage_key_init_range(paddr, paddr + size - 1); + __storage_key_init_range(paddr, paddr + size); } void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, @@ -224,7 +224,7 @@ if (p4d_present(*p4dp)) { pudp = pud_offset(p4dp, addr); if (pud_present(*pudp)) { - if (pud_large(*pudp)) + if (pud_leaf(*pudp)) return (pte_t *) pudp; pmdp = pmd_offset(pudp, addr); } @@ -240,7 +240,7 @@ int pud_huge(pud_t pud) { - return pud_large(pud); + return pud_leaf(pud); } bool __init arch_hugetlb_valid_size(unsigned long size) --- linux-xilinx-6.8.0.orig/arch/s390/mm/init.c +++ linux-xilinx-6.8.0/arch/s390/mm/init.c @@ -281,9 +281,6 @@ unsigned long size_pages = PFN_DOWN(size); int rc; - if (WARN_ON_ONCE(params->altmap)) - return -EINVAL; - if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)) return -EINVAL; --- linux-xilinx-6.8.0.orig/arch/s390/mm/pageattr.c +++ linux-xilinx-6.8.0/arch/s390/mm/pageattr.c @@ -274,7 +274,7 @@ if (pud_none(*pudp)) return -EINVAL; next = pud_addr_end(addr, end); - if (pud_large(*pudp)) { + if (pud_leaf(*pudp)) { need_split = !!(flags & SET_MEMORY_4K); need_split |= !!(addr & ~PUD_MASK); need_split |= !!(addr + PUD_SIZE > next); --- linux-xilinx-6.8.0.orig/arch/s390/mm/pgalloc.c +++ linux-xilinx-6.8.0/arch/s390/mm/pgalloc.c @@ -55,6 +55,8 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table) { + if (!table) + return; pagetable_free(virt_to_ptdesc(table)); } @@ -262,6 +264,8 @@ static void base_crst_free(unsigned long *table) { + if (!table) + return; pagetable_free(virt_to_ptdesc(table)); } --- linux-xilinx-6.8.0.orig/arch/s390/mm/pgtable.c +++ linux-xilinx-6.8.0/arch/s390/mm/pgtable.c @@ -470,7 +470,7 @@ return -ENOENT; /* Large PUDs are not supported yet. */ - if (pud_large(*pud)) + if (pud_leaf(*pud)) return -EFAULT; *pmdp = pmd_offset(pud, addr); --- linux-xilinx-6.8.0.orig/arch/s390/mm/vmem.c +++ linux-xilinx-6.8.0/arch/s390/mm/vmem.c @@ -33,8 +33,12 @@ return memblock_alloc(size, size); } -static void vmem_free_pages(unsigned long addr, int order) +static void vmem_free_pages(unsigned long addr, int order, struct vmem_altmap *altmap) { + if (altmap) { + vmem_altmap_free(altmap, 1 << order); + return; + } /* We don't expect boot memory to be removed ever. */ if (!slab_is_available() || WARN_ON_ONCE(PageReserved(virt_to_page((void *)addr)))) @@ -156,7 +160,8 @@ /* __ref: we'll only call vmemmap_alloc_block() via vmemmap_populate() */ static int __ref modify_pte_table(pmd_t *pmd, unsigned long addr, - unsigned long end, bool add, bool direct) + unsigned long end, bool add, bool direct, + struct vmem_altmap *altmap) { unsigned long prot, pages = 0; int ret = -ENOMEM; @@ -172,11 +177,11 @@ if (pte_none(*pte)) continue; if (!direct) - vmem_free_pages((unsigned long) pfn_to_virt(pte_pfn(*pte)), 0); + vmem_free_pages((unsigned long)pfn_to_virt(pte_pfn(*pte)), get_order(PAGE_SIZE), altmap); pte_clear(&init_mm, addr, pte); } else if (pte_none(*pte)) { if (!direct) { - void *new_page = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE); + void *new_page = vmemmap_alloc_block_buf(PAGE_SIZE, NUMA_NO_NODE, altmap); if (!new_page) goto out; @@ -213,7 +218,8 @@ /* __ref: we'll only call vmemmap_alloc_block() via vmemmap_populate() */ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr, - unsigned long end, bool add, bool direct) + unsigned long end, bool add, bool direct, + struct vmem_altmap *altmap) { unsigned long next, prot, pages = 0; int ret = -ENOMEM; @@ -234,11 +240,11 @@ if (IS_ALIGNED(addr, PMD_SIZE) && IS_ALIGNED(next, PMD_SIZE)) { if (!direct) - vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE)); + vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE), altmap); pmd_clear(pmd); pages++; } else if (!direct && vmemmap_unuse_sub_pmd(addr, next)) { - vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE)); + vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE), altmap); pmd_clear(pmd); } continue; @@ -261,7 +267,7 @@ * page tables since vmemmap_populate gets * called for each section separately. */ - new_page = vmemmap_alloc_block(PMD_SIZE, NUMA_NO_NODE); + new_page = vmemmap_alloc_block_buf(PMD_SIZE, NUMA_NO_NODE, altmap); if (new_page) { set_pmd(pmd, __pmd(__pa(new_page) | prot)); if (!IS_ALIGNED(addr, PMD_SIZE) || @@ -280,7 +286,7 @@ vmemmap_use_sub_pmd(addr, next); continue; } - ret = modify_pte_table(pmd, addr, next, add, direct); + ret = modify_pte_table(pmd, addr, next, add, direct, altmap); if (ret) goto out; if (!add) @@ -302,12 +308,12 @@ for (i = 0; i < PTRS_PER_PMD; i++, pmd++) if (!pmd_none(*pmd)) return; - vmem_free_pages(pud_deref(*pud), CRST_ALLOC_ORDER); + vmem_free_pages(pud_deref(*pud), CRST_ALLOC_ORDER, NULL); pud_clear(pud); } static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end, - bool add, bool direct) + bool add, bool direct, struct vmem_altmap *altmap) { unsigned long next, prot, pages = 0; int ret = -ENOMEM; @@ -323,7 +329,7 @@ if (!add) { if (pud_none(*pud)) continue; - if (pud_large(*pud)) { + if (pud_leaf(*pud)) { if (IS_ALIGNED(addr, PUD_SIZE) && IS_ALIGNED(next, PUD_SIZE)) { pud_clear(pud); @@ -344,10 +350,10 @@ if (!pmd) goto out; pud_populate(&init_mm, pud, pmd); - } else if (pud_large(*pud)) { + } else if (pud_leaf(*pud)) { continue; } - ret = modify_pmd_table(pud, addr, next, add, direct); + ret = modify_pmd_table(pud, addr, next, add, direct, altmap); if (ret) goto out; if (!add) @@ -370,12 +376,12 @@ if (!pud_none(*pud)) return; } - vmem_free_pages(p4d_deref(*p4d), CRST_ALLOC_ORDER); + vmem_free_pages(p4d_deref(*p4d), CRST_ALLOC_ORDER, NULL); p4d_clear(p4d); } static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end, - bool add, bool direct) + bool add, bool direct, struct vmem_altmap *altmap) { unsigned long next; int ret = -ENOMEM; @@ -394,7 +400,7 @@ goto out; p4d_populate(&init_mm, p4d, pud); } - ret = modify_pud_table(p4d, addr, next, add, direct); + ret = modify_pud_table(p4d, addr, next, add, direct, altmap); if (ret) goto out; if (!add) @@ -415,12 +421,12 @@ if (!p4d_none(*p4d)) return; } - vmem_free_pages(pgd_deref(*pgd), CRST_ALLOC_ORDER); + vmem_free_pages(pgd_deref(*pgd), CRST_ALLOC_ORDER, NULL); pgd_clear(pgd); } static int modify_pagetable(unsigned long start, unsigned long end, bool add, - bool direct) + bool direct, struct vmem_altmap *altmap) { unsigned long addr, next; int ret = -ENOMEM; @@ -445,7 +451,7 @@ goto out; pgd_populate(&init_mm, pgd, p4d); } - ret = modify_p4d_table(pgd, addr, next, add, direct); + ret = modify_p4d_table(pgd, addr, next, add, direct, altmap); if (ret) goto out; if (!add) @@ -458,14 +464,16 @@ return ret; } -static int add_pagetable(unsigned long start, unsigned long end, bool direct) +static int add_pagetable(unsigned long start, unsigned long end, bool direct, + struct vmem_altmap *altmap) { - return modify_pagetable(start, end, true, direct); + return modify_pagetable(start, end, true, direct, altmap); } -static int remove_pagetable(unsigned long start, unsigned long end, bool direct) +static int remove_pagetable(unsigned long start, unsigned long end, bool direct, + struct vmem_altmap *altmap) { - return modify_pagetable(start, end, false, direct); + return modify_pagetable(start, end, false, direct, altmap); } /* @@ -474,7 +482,7 @@ static int vmem_add_range(unsigned long start, unsigned long size) { start = (unsigned long)__va(start); - return add_pagetable(start, start + size, true); + return add_pagetable(start, start + size, true, NULL); } /* @@ -483,7 +491,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size) { start = (unsigned long)__va(start); - remove_pagetable(start, start + size, true); + remove_pagetable(start, start + size, true, NULL); } /* @@ -496,9 +504,9 @@ mutex_lock(&vmem_mutex); /* We don't care about the node, just use NUMA_NO_NODE on allocations */ - ret = add_pagetable(start, end, false); + ret = add_pagetable(start, end, false, altmap); if (ret) - remove_pagetable(start, end, false); + remove_pagetable(start, end, false, altmap); mutex_unlock(&vmem_mutex); return ret; } @@ -509,7 +517,7 @@ struct vmem_altmap *altmap) { mutex_lock(&vmem_mutex); - remove_pagetable(start, end, false); + remove_pagetable(start, end, false, altmap); mutex_unlock(&vmem_mutex); } @@ -591,7 +599,7 @@ if (!pmd) goto out; pud_populate(&init_mm, pud, pmd); - } else if (WARN_ON_ONCE(pud_large(*pud))) { + } else if (WARN_ON_ONCE(pud_leaf(*pud))) { goto out; } pmd = pmd_offset(pud, addr); --- linux-xilinx-6.8.0.orig/arch/s390/net/bpf_jit_comp.c +++ linux-xilinx-6.8.0/arch/s390/net/bpf_jit_comp.c @@ -516,11 +516,12 @@ * PLT for hotpatchable calls. The calling convention is the same as for the * ftrace hotpatch trampolines: %r0 is return address, %r1 is clobbered. */ -extern const char bpf_plt[]; -extern const char bpf_plt_ret[]; -extern const char bpf_plt_target[]; -extern const char bpf_plt_end[]; -#define BPF_PLT_SIZE 32 +struct bpf_plt { + char code[16]; + void *ret; + void *target; +} __packed; +extern const struct bpf_plt bpf_plt; asm( ".pushsection .rodata\n" " .balign 8\n" @@ -531,15 +532,14 @@ " .balign 8\n" "bpf_plt_ret: .quad 0\n" "bpf_plt_target: .quad 0\n" - "bpf_plt_end:\n" " .popsection\n" ); -static void bpf_jit_plt(void *plt, void *ret, void *target) +static void bpf_jit_plt(struct bpf_plt *plt, void *ret, void *target) { - memcpy(plt, bpf_plt, BPF_PLT_SIZE); - *(void **)((char *)plt + (bpf_plt_ret - bpf_plt)) = ret; - *(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target ?: ret; + memcpy(plt, &bpf_plt, sizeof(*plt)); + plt->ret = ret; + plt->target = target; } /* @@ -662,9 +662,9 @@ jit->prg = ALIGN(jit->prg, 8); jit->prologue_plt = jit->prg; if (jit->prg_buf) - bpf_jit_plt(jit->prg_buf + jit->prg, + bpf_jit_plt((struct bpf_plt *)(jit->prg_buf + jit->prg), jit->prg_buf + jit->prologue_plt_ret, NULL); - jit->prg += BPF_PLT_SIZE; + jit->prg += sizeof(struct bpf_plt); } static int get_probe_mem_regno(const u8 *insn) @@ -1427,8 +1427,12 @@ EMIT6_DISP_LH(0xeb000000, is32 ? (op32) : (op64), \ (insn->imm & BPF_FETCH) ? src_reg : REG_W0, \ src_reg, dst_reg, off); \ - if (is32 && (insn->imm & BPF_FETCH)) \ - EMIT_ZERO(src_reg); \ + if (insn->imm & BPF_FETCH) { \ + /* bcr 14,0 - see atomic_fetch_{add,and,or,xor}() */ \ + _EMIT2(0x07e0); \ + if (is32) \ + EMIT_ZERO(src_reg); \ + } \ } while (0) case BPF_ADD: case BPF_ADD | BPF_FETCH: @@ -2040,9 +2044,6 @@ struct bpf_jit jit; int pass; - if (WARN_ON_ONCE(bpf_plt_end - bpf_plt != BPF_PLT_SIZE)) - return orig_fp; - if (!fp->jit_requested) return orig_fp; @@ -2111,7 +2112,11 @@ print_fn_code(jit.prg_buf, jit.size_prg); } if (!fp->is_func || extra_pass) { - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) { + bpf_jit_binary_free(header); + fp = orig_fp; + goto free_addrs; + } } else { jit_data->header = header; jit_data->ctx = jit; @@ -2148,14 +2153,11 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, void *old_addr, void *new_addr) { + struct bpf_plt expected_plt, current_plt, new_plt, *plt; struct { u16 opc; s32 disp; } __packed insn; - char expected_plt[BPF_PLT_SIZE]; - char current_plt[BPF_PLT_SIZE]; - char new_plt[BPF_PLT_SIZE]; - char *plt; char *ret; int err; @@ -2174,18 +2176,18 @@ */ } else { /* Verify the PLT. */ - plt = (char *)ip + (insn.disp << 1); - err = copy_from_kernel_nofault(current_plt, plt, BPF_PLT_SIZE); + plt = ip + (insn.disp << 1); + err = copy_from_kernel_nofault(¤t_plt, plt, + sizeof(current_plt)); if (err < 0) return err; ret = (char *)ip + 6; - bpf_jit_plt(expected_plt, ret, old_addr); - if (memcmp(current_plt, expected_plt, BPF_PLT_SIZE)) + bpf_jit_plt(&expected_plt, ret, old_addr); + if (memcmp(¤t_plt, &expected_plt, sizeof(current_plt))) return -EINVAL; /* Adjust the call address. */ - bpf_jit_plt(new_plt, ret, new_addr); - s390_kernel_write(plt + (bpf_plt_target - bpf_plt), - new_plt + (bpf_plt_target - bpf_plt), + bpf_jit_plt(&new_plt, ret, new_addr); + s390_kernel_write(&plt->target, &new_plt.target, sizeof(void *)); } --- linux-xilinx-6.8.0.orig/arch/s390/pci/pci_irq.c +++ linux-xilinx-6.8.0/arch/s390/pci/pci_irq.c @@ -410,7 +410,7 @@ union zpci_sic_iib iib = {{0}}; union zpci_sic_iib ziib = {{0}}; - iib.cdiib.dibv_addr = (u64) zpci_ibv[smp_processor_id()]->vector; + iib.cdiib.dibv_addr = virt_to_phys(zpci_ibv[smp_processor_id()]->vector); zpci_set_irq_ctrl(SIC_IRQ_MODE_SET_CPU, 0, &iib); zpci_set_irq_ctrl(SIC_IRQ_MODE_D_SINGLE, PCI_ISC, &ziib); --- linux-xilinx-6.8.0.orig/arch/sh/kernel/kprobes.c +++ linux-xilinx-6.8.0/arch/sh/kernel/kprobes.c @@ -44,17 +44,12 @@ if (OPCODE_RTE(opcode)) return -EFAULT; /* Bad breakpoint */ + memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); p->opcode = opcode; return 0; } -void __kprobes arch_copy_kprobe(struct kprobe *p) -{ - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); - p->opcode = *p->addr; -} - void __kprobes arch_arm_kprobe(struct kprobe *p) { *p->addr = BREAKPOINT_INSTRUCTION; --- linux-xilinx-6.8.0.orig/arch/sh/kernel/sys_sh32.c +++ linux-xilinx-6.8.0/arch/sh/kernel/sys_sh32.c @@ -59,3 +59,14 @@ (u64)len0 << 32 | len1, advice); #endif } + +/* + * swap the arguments the way that libc wants them instead of + * moving flags ahead of the 64-bit nbytes argument + */ +SYSCALL_DEFINE6(sh_sync_file_range6, int, fd, SC_ARG64(offset), + SC_ARG64(nbytes), unsigned int, flags) +{ + return ksys_sync_file_range(fd, SC_VAL64(loff_t, offset), + SC_VAL64(loff_t, nbytes), flags); +} --- linux-xilinx-6.8.0.orig/arch/sh/kernel/syscalls/syscall.tbl +++ linux-xilinx-6.8.0/arch/sh/kernel/syscalls/syscall.tbl @@ -321,7 +321,7 @@ 311 common set_robust_list sys_set_robust_list 312 common get_robust_list sys_get_robust_list 313 common splice sys_splice -314 common sync_file_range sys_sync_file_range +314 common sync_file_range sys_sh_sync_file_range6 315 common tee sys_tee 316 common vmsplice sys_vmsplice 317 common move_pages sys_move_pages @@ -395,6 +395,7 @@ 385 common pkey_alloc sys_pkey_alloc 386 common pkey_free sys_pkey_free 387 common rseq sys_rseq +388 common sync_file_range2 sys_sync_file_range2 # room for arch specific syscalls 393 common semget sys_semget 394 common semctl sys_semctl --- linux-xilinx-6.8.0.orig/arch/sh/lib/checksum.S +++ linux-xilinx-6.8.0/arch/sh/lib/checksum.S @@ -33,7 +33,8 @@ */ /* - * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum); + * unsigned int csum_partial(const unsigned char *buf, int len, + * unsigned int sum); */ .text @@ -45,31 +46,11 @@ * Fortunately, it is easy to convert 2-byte alignment to 4-byte * alignment for the unrolled loop. */ + mov r5, r1 mov r4, r0 - tst #3, r0 ! Check alignment. - bt/s 2f ! Jump if alignment is ok. - mov r4, r7 ! Keep a copy to check for alignment + tst #2, r0 ! Check alignment. + bt 2f ! Jump if alignment is ok. ! - tst #1, r0 ! Check alignment. - bt 21f ! Jump if alignment is boundary of 2bytes. - - ! buf is odd - tst r5, r5 - add #-1, r5 - bt 9f - mov.b @r4+, r0 - extu.b r0, r0 - addc r0, r6 ! t=0 from previous tst - mov r6, r0 - shll8 r6 - shlr16 r0 - shlr8 r0 - or r0, r6 - mov r4, r0 - tst #2, r0 - bt 2f -21: - ! buf is 2 byte aligned (len could be 0) add #-2, r5 ! Alignment uses up two bytes. cmp/pz r5 ! bt/s 1f ! Jump if we had at least two bytes. @@ -77,17 +58,16 @@ bra 6f add #2, r5 ! r5 was < 2. Deal with it. 1: + mov r5, r1 ! Save new len for later use. mov.w @r4+, r0 extu.w r0, r0 addc r0, r6 bf 2f add #1, r6 2: - ! buf is 4 byte aligned (len could be 0) - mov r5, r1 mov #-5, r0 - shld r0, r1 - tst r1, r1 + shld r0, r5 + tst r5, r5 bt/s 4f ! if it's =0, go to 4f clrt .align 2 @@ -109,31 +89,30 @@ addc r0, r6 addc r2, r6 movt r0 - dt r1 + dt r5 bf/s 3b cmp/eq #1, r0 - ! here, we know r1==0 - addc r1, r6 ! add carry to r6 + ! here, we know r5==0 + addc r5, r6 ! add carry to r6 4: - mov r5, r0 + mov r1, r0 and #0x1c, r0 tst r0, r0 - bt 6f - ! 4 bytes or more remaining - mov r0, r1 - shlr2 r1 + bt/s 6f + mov r0, r5 + shlr2 r5 mov #0, r2 5: addc r2, r6 mov.l @r4+, r2 movt r0 - dt r1 + dt r5 bf/s 5b cmp/eq #1, r0 addc r2, r6 - addc r1, r6 ! r1==0 here, so it means add carry-bit + addc r5, r6 ! r5==0 here, so it means add carry-bit 6: - ! 3 bytes or less remaining + mov r1, r5 mov #3, r0 and r0, r5 tst r5, r5 @@ -159,16 +138,6 @@ mov #0, r0 addc r0, r6 9: - ! Check if the buffer was misaligned, if so realign sum - mov r7, r0 - tst #1, r0 - bt 10f - mov r6, r0 - shll8 r6 - shlr16 r0 - shlr8 r0 - or r0, r6 -10: rts mov r6, r0 --- linux-xilinx-6.8.0.orig/arch/sparc/Kconfig +++ linux-xilinx-6.8.0/arch/sparc/Kconfig @@ -57,6 +57,8 @@ select CLZ_TAB select DMA_DIRECT_REMAP select GENERIC_ATOMIC64 + select GENERIC_LIB_CMPDI2 + select GENERIC_LIB_UCMPDI2 select HAVE_UID16 select LOCK_MM_AND_FIND_VMA select OLD_SIGACTION @@ -140,10 +142,6 @@ default y if SPARC32 select KMAP_LOCAL -config GENERIC_ISA_DMA - bool - default y if SPARC32 - config PGTABLE_LEVELS default 4 if 64BIT default 3 --- linux-xilinx-6.8.0.orig/arch/sparc/include/asm/parport.h +++ linux-xilinx-6.8.0/arch/sparc/include/asm/parport.h @@ -1,256 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* parport.h: sparc64 specific parport initialization and dma. - * - * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) - */ +#ifndef ___ASM_SPARC_PARPORT_H +#define ___ASM_SPARC_PARPORT_H -#ifndef _ASM_SPARC64_PARPORT_H -#define _ASM_SPARC64_PARPORT_H 1 - -#include -#include - -#include -#include -#include - -#define PARPORT_PC_MAX_PORTS PARPORT_MAX - -/* - * While sparc64 doesn't have an ISA DMA API, we provide something that looks - * close enough to make parport_pc happy - */ -#define HAS_DMA - -#ifdef CONFIG_PARPORT_PC_FIFO -static DEFINE_SPINLOCK(dma_spin_lock); - -#define claim_dma_lock() \ -({ unsigned long flags; \ - spin_lock_irqsave(&dma_spin_lock, flags); \ - flags; \ -}) - -#define release_dma_lock(__flags) \ - spin_unlock_irqrestore(&dma_spin_lock, __flags); +#if defined(__sparc__) && defined(__arch64__) +#include +#else +#include +#endif #endif -static struct sparc_ebus_info { - struct ebus_dma_info info; - unsigned int addr; - unsigned int count; - int lock; - - struct parport *port; -} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; - -static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS); - -static inline int request_dma(unsigned int dmanr, const char *device_id) -{ - if (dmanr >= PARPORT_PC_MAX_PORTS) - return -EINVAL; - if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0) - return -EBUSY; - return 0; -} - -static inline void free_dma(unsigned int dmanr) -{ - if (dmanr >= PARPORT_PC_MAX_PORTS) { - printk(KERN_WARNING "Trying to free DMA%d\n", dmanr); - return; - } - if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) { - printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr); - return; - } -} - -static inline void enable_dma(unsigned int dmanr) -{ - ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); - - if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info, - sparc_ebus_dmas[dmanr].addr, - sparc_ebus_dmas[dmanr].count)) - BUG(); -} - -static inline void disable_dma(unsigned int dmanr) -{ - ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0); -} - -static inline void clear_dma_ff(unsigned int dmanr) -{ - /* nothing */ -} - -static inline void set_dma_mode(unsigned int dmanr, char mode) -{ - ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE)); -} - -static inline void set_dma_addr(unsigned int dmanr, unsigned int addr) -{ - sparc_ebus_dmas[dmanr].addr = addr; -} - -static inline void set_dma_count(unsigned int dmanr, unsigned int count) -{ - sparc_ebus_dmas[dmanr].count = count; -} - -static inline unsigned int get_dma_residue(unsigned int dmanr) -{ - return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); -} - -static int ecpp_probe(struct platform_device *op) -{ - unsigned long base = op->resource[0].start; - unsigned long config = op->resource[1].start; - unsigned long d_base = op->resource[2].start; - unsigned long d_len; - struct device_node *parent; - struct parport *p; - int slot, err; - - parent = op->dev.of_node->parent; - if (of_node_name_eq(parent, "dma")) { - p = parport_pc_probe_port(base, base + 0x400, - op->archdata.irqs[0], PARPORT_DMA_NOFIFO, - op->dev.parent->parent, 0); - if (!p) - return -ENOMEM; - dev_set_drvdata(&op->dev, p); - return 0; - } - - for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) { - if (!test_and_set_bit(slot, dma_slot_map)) - break; - } - err = -ENODEV; - if (slot >= PARPORT_PC_MAX_PORTS) - goto out_err; - - spin_lock_init(&sparc_ebus_dmas[slot].info.lock); - - d_len = (op->resource[2].end - d_base) + 1UL; - sparc_ebus_dmas[slot].info.regs = - of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA"); - - if (!sparc_ebus_dmas[slot].info.regs) - goto out_clear_map; - - sparc_ebus_dmas[slot].info.flags = 0; - sparc_ebus_dmas[slot].info.callback = NULL; - sparc_ebus_dmas[slot].info.client_cookie = NULL; - sparc_ebus_dmas[slot].info.irq = 0xdeadbeef; - strcpy(sparc_ebus_dmas[slot].info.name, "parport"); - if (ebus_dma_register(&sparc_ebus_dmas[slot].info)) - goto out_unmap_regs; - - ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1); - - /* Configure IRQ to Push Pull, Level Low */ - /* Enable ECP, set bit 2 of the CTR first */ - outb(0x04, base + 0x02); - ns87303_modify(config, PCR, - PCR_EPP_ENABLE | - PCR_IRQ_ODRAIN, - PCR_ECP_ENABLE | - PCR_ECP_CLK_ENA | - PCR_IRQ_POLAR); - - /* CTR bit 5 controls direction of port */ - ns87303_modify(config, PTR, - 0, PTR_LPT_REG_DIR); - - p = parport_pc_probe_port(base, base + 0x400, - op->archdata.irqs[0], - slot, - op->dev.parent, - 0); - err = -ENOMEM; - if (!p) - goto out_disable_irq; - - dev_set_drvdata(&op->dev, p); - - return 0; - -out_disable_irq: - ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); - ebus_dma_unregister(&sparc_ebus_dmas[slot].info); - -out_unmap_regs: - of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len); - -out_clear_map: - clear_bit(slot, dma_slot_map); - -out_err: - return err; -} - -static int ecpp_remove(struct platform_device *op) -{ - struct parport *p = dev_get_drvdata(&op->dev); - int slot = p->dma; - - parport_pc_unregister_port(p); - - if (slot != PARPORT_DMA_NOFIFO) { - unsigned long d_base = op->resource[2].start; - unsigned long d_len; - - d_len = (op->resource[2].end - d_base) + 1UL; - - ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); - ebus_dma_unregister(&sparc_ebus_dmas[slot].info); - of_iounmap(&op->resource[2], - sparc_ebus_dmas[slot].info.regs, - d_len); - clear_bit(slot, dma_slot_map); - } - - return 0; -} - -static const struct of_device_id ecpp_match[] = { - { - .name = "ecpp", - }, - { - .name = "parallel", - .compatible = "ecpp", - }, - { - .name = "parallel", - .compatible = "ns87317-ecpp", - }, - { - .name = "parallel", - .compatible = "pnpALI,1533,3", - }, - {}, -}; - -static struct platform_driver ecpp_driver = { - .driver = { - .name = "ecpp", - .of_match_table = ecpp_match, - }, - .probe = ecpp_probe, - .remove = ecpp_remove, -}; - -static int parport_pc_find_nonpci_ports(int autoirq, int autodma) -{ - return platform_driver_register(&ecpp_driver); -} - -#endif /* !(_ASM_SPARC64_PARPORT_H */ --- linux-xilinx-6.8.0.orig/arch/sparc/include/asm/parport_64.h +++ linux-xilinx-6.8.0/arch/sparc/include/asm/parport_64.h @@ -0,0 +1,256 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* parport.h: sparc64 specific parport initialization and dma. + * + * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) + */ + +#ifndef _ASM_SPARC64_PARPORT_H +#define _ASM_SPARC64_PARPORT_H 1 + +#include +#include + +#include +#include +#include + +#define PARPORT_PC_MAX_PORTS PARPORT_MAX + +/* + * While sparc64 doesn't have an ISA DMA API, we provide something that looks + * close enough to make parport_pc happy + */ +#define HAS_DMA + +#ifdef CONFIG_PARPORT_PC_FIFO +static DEFINE_SPINLOCK(dma_spin_lock); + +#define claim_dma_lock() \ +({ unsigned long flags; \ + spin_lock_irqsave(&dma_spin_lock, flags); \ + flags; \ +}) + +#define release_dma_lock(__flags) \ + spin_unlock_irqrestore(&dma_spin_lock, __flags); +#endif + +static struct sparc_ebus_info { + struct ebus_dma_info info; + unsigned int addr; + unsigned int count; + int lock; + + struct parport *port; +} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS]; + +static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS); + +static inline int request_dma(unsigned int dmanr, const char *device_id) +{ + if (dmanr >= PARPORT_PC_MAX_PORTS) + return -EINVAL; + if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0) + return -EBUSY; + return 0; +} + +static inline void free_dma(unsigned int dmanr) +{ + if (dmanr >= PARPORT_PC_MAX_PORTS) { + printk(KERN_WARNING "Trying to free DMA%d\n", dmanr); + return; + } + if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) { + printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr); + return; + } +} + +static inline void enable_dma(unsigned int dmanr) +{ + ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); + + if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info, + sparc_ebus_dmas[dmanr].addr, + sparc_ebus_dmas[dmanr].count)) + BUG(); +} + +static inline void disable_dma(unsigned int dmanr) +{ + ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0); +} + +static inline void clear_dma_ff(unsigned int dmanr) +{ + /* nothing */ +} + +static inline void set_dma_mode(unsigned int dmanr, char mode) +{ + ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE)); +} + +static inline void set_dma_addr(unsigned int dmanr, unsigned int addr) +{ + sparc_ebus_dmas[dmanr].addr = addr; +} + +static inline void set_dma_count(unsigned int dmanr, unsigned int count) +{ + sparc_ebus_dmas[dmanr].count = count; +} + +static inline unsigned int get_dma_residue(unsigned int dmanr) +{ + return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info); +} + +static int ecpp_probe(struct platform_device *op) +{ + unsigned long base = op->resource[0].start; + unsigned long config = op->resource[1].start; + unsigned long d_base = op->resource[2].start; + unsigned long d_len; + struct device_node *parent; + struct parport *p; + int slot, err; + + parent = op->dev.of_node->parent; + if (of_node_name_eq(parent, "dma")) { + p = parport_pc_probe_port(base, base + 0x400, + op->archdata.irqs[0], PARPORT_DMA_NOFIFO, + op->dev.parent->parent, 0); + if (!p) + return -ENOMEM; + dev_set_drvdata(&op->dev, p); + return 0; + } + + for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) { + if (!test_and_set_bit(slot, dma_slot_map)) + break; + } + err = -ENODEV; + if (slot >= PARPORT_PC_MAX_PORTS) + goto out_err; + + spin_lock_init(&sparc_ebus_dmas[slot].info.lock); + + d_len = (op->resource[2].end - d_base) + 1UL; + sparc_ebus_dmas[slot].info.regs = + of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA"); + + if (!sparc_ebus_dmas[slot].info.regs) + goto out_clear_map; + + sparc_ebus_dmas[slot].info.flags = 0; + sparc_ebus_dmas[slot].info.callback = NULL; + sparc_ebus_dmas[slot].info.client_cookie = NULL; + sparc_ebus_dmas[slot].info.irq = 0xdeadbeef; + strcpy(sparc_ebus_dmas[slot].info.name, "parport"); + if (ebus_dma_register(&sparc_ebus_dmas[slot].info)) + goto out_unmap_regs; + + ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1); + + /* Configure IRQ to Push Pull, Level Low */ + /* Enable ECP, set bit 2 of the CTR first */ + outb(0x04, base + 0x02); + ns87303_modify(config, PCR, + PCR_EPP_ENABLE | + PCR_IRQ_ODRAIN, + PCR_ECP_ENABLE | + PCR_ECP_CLK_ENA | + PCR_IRQ_POLAR); + + /* CTR bit 5 controls direction of port */ + ns87303_modify(config, PTR, + 0, PTR_LPT_REG_DIR); + + p = parport_pc_probe_port(base, base + 0x400, + op->archdata.irqs[0], + slot, + op->dev.parent, + 0); + err = -ENOMEM; + if (!p) + goto out_disable_irq; + + dev_set_drvdata(&op->dev, p); + + return 0; + +out_disable_irq: + ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); + ebus_dma_unregister(&sparc_ebus_dmas[slot].info); + +out_unmap_regs: + of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len); + +out_clear_map: + clear_bit(slot, dma_slot_map); + +out_err: + return err; +} + +static int ecpp_remove(struct platform_device *op) +{ + struct parport *p = dev_get_drvdata(&op->dev); + int slot = p->dma; + + parport_pc_unregister_port(p); + + if (slot != PARPORT_DMA_NOFIFO) { + unsigned long d_base = op->resource[2].start; + unsigned long d_len; + + d_len = (op->resource[2].end - d_base) + 1UL; + + ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0); + ebus_dma_unregister(&sparc_ebus_dmas[slot].info); + of_iounmap(&op->resource[2], + sparc_ebus_dmas[slot].info.regs, + d_len); + clear_bit(slot, dma_slot_map); + } + + return 0; +} + +static const struct of_device_id ecpp_match[] = { + { + .name = "ecpp", + }, + { + .name = "parallel", + .compatible = "ecpp", + }, + { + .name = "parallel", + .compatible = "ns87317-ecpp", + }, + { + .name = "parallel", + .compatible = "pnpALI,1533,3", + }, + {}, +}; + +static struct platform_driver ecpp_driver = { + .driver = { + .name = "ecpp", + .of_match_table = ecpp_match, + }, + .probe = ecpp_probe, + .remove = ecpp_remove, +}; + +static int parport_pc_find_nonpci_ports(int autoirq, int autodma) +{ + return platform_driver_register(&ecpp_driver); +} + +#endif /* !(_ASM_SPARC64_PARPORT_H */ --- linux-xilinx-6.8.0.orig/arch/sparc/include/asm/smp_64.h +++ linux-xilinx-6.8.0/arch/sparc/include/asm/smp_64.h @@ -47,7 +47,6 @@ int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu) -void smp_fill_in_cpu_possible_map(void); void smp_fill_in_sib_core_maps(void); void __noreturn cpu_play_dead(void); @@ -77,7 +76,6 @@ #define smp_fill_in_sib_core_maps() do { } while (0) #define smp_fetch_global_regs() do { } while (0) #define smp_fetch_global_pmu() do { } while (0) -#define smp_fill_in_cpu_possible_map() do { } while (0) #define smp_init_cpu_poke() do { } while (0) #define scheduler_poke() do { } while (0) --- linux-xilinx-6.8.0.orig/arch/sparc/include/uapi/asm/termbits.h +++ linux-xilinx-6.8.0/arch/sparc/include/uapi/asm/termbits.h @@ -10,16 +10,6 @@ typedef unsigned long tcflag_t; #endif -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - #define NCCS 17 struct termios { tcflag_t c_iflag; /* input mode flags */ --- linux-xilinx-6.8.0.orig/arch/sparc/include/uapi/asm/termios.h +++ linux-xilinx-6.8.0/arch/sparc/include/uapi/asm/termios.h @@ -40,5 +40,14 @@ unsigned short ws_ypixel; }; +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; #endif /* _UAPI_SPARC_TERMIOS_H */ --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/leon_pci_grpci1.c +++ linux-xilinx-6.8.0/arch/sparc/kernel/leon_pci_grpci1.c @@ -697,7 +697,7 @@ return err; } -static const struct of_device_id grpci1_of_match[] __initconst = { +static const struct of_device_id grpci1_of_match[] = { { .name = "GAISLER_PCIFBRG", }, --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/leon_pci_grpci2.c +++ linux-xilinx-6.8.0/arch/sparc/kernel/leon_pci_grpci2.c @@ -889,7 +889,7 @@ return err; } -static const struct of_device_id grpci2_of_match[] __initconst = { +static const struct of_device_id grpci2_of_match[] = { { .name = "GAISLER_GRPCI2", }, --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/nmi.c +++ linux-xilinx-6.8.0/arch/sparc/kernel/nmi.c @@ -279,7 +279,7 @@ if (!strncmp(str, "panic", 5)) panic_on_timeout = 1; - return 0; + return 1; } __setup("nmi_watchdog=", setup_nmi_watchdog); --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/prom_64.c +++ linux-xilinx-6.8.0/arch/sparc/kernel/prom_64.c @@ -483,7 +483,9 @@ ncpus_probed++; #ifdef CONFIG_SMP set_cpu_present(cpuid, true); - set_cpu_possible(cpuid, true); + + if (num_possible_cpus() < nr_cpu_ids) + set_cpu_possible(cpuid, true); #endif return NULL; } --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/setup_64.c +++ linux-xilinx-6.8.0/arch/sparc/kernel/setup_64.c @@ -671,7 +671,6 @@ paging_init(); init_sparc64_elf_hwcap(); - smp_fill_in_cpu_possible_map(); /* * Once the OF device tree and MDESC have been setup and nr_cpus has * been parsed, we know the list of possible cpus. Therefore we can --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/smp_64.c +++ linux-xilinx-6.8.0/arch/sparc/kernel/smp_64.c @@ -1220,20 +1220,6 @@ xcall_deliver_impl = hypervisor_xcall_deliver; } -void __init smp_fill_in_cpu_possible_map(void) -{ - int possible_cpus = num_possible_cpus(); - int i; - - if (possible_cpus > nr_cpu_ids) - possible_cpus = nr_cpu_ids; - - for (i = 0; i < possible_cpus; i++) - set_cpu_possible(i, true); - for (; i < NR_CPUS; i++) - set_cpu_possible(i, false); -} - void smp_fill_in_sib_core_maps(void) { unsigned int i; --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/sys32.S +++ linux-xilinx-6.8.0/arch/sparc/kernel/sys32.S @@ -18,224 +18,3 @@ sethi %hi(sys_mmap), %g1 jmpl %g1 + %lo(sys_mmap), %g0 sllx %o5, 12, %o5 - - .align 32 - .globl sys32_socketcall -sys32_socketcall: /* %o0=call, %o1=args */ - cmp %o0, 1 - bl,pn %xcc, do_einval - cmp %o0, 18 - bg,pn %xcc, do_einval - sub %o0, 1, %o0 - sllx %o0, 5, %o0 - sethi %hi(__socketcall_table_begin), %g2 - or %g2, %lo(__socketcall_table_begin), %g2 - jmpl %g2 + %o0, %g0 - nop -do_einval: - retl - mov -EINVAL, %o0 - - .align 32 -__socketcall_table_begin: - - /* Each entry is exactly 32 bytes. */ -do_sys_socket: /* sys_socket(int, int, int) */ -1: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_socket), %g1 -2: ldswa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(sys_socket), %g0 -3: ldswa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */ -4: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_bind), %g1 -5: ldswa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(sys_bind), %g0 -6: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */ -7: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_connect), %g1 -8: ldswa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(sys_connect), %g0 -9: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_listen: /* sys_listen(int, int) */ -10: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_listen), %g1 - jmpl %g1 + %lo(sys_listen), %g0 -11: ldswa [%o1 + 0x4] %asi, %o1 - nop - nop - nop - nop -do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */ -12: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_accept), %g1 -13: lduwa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(sys_accept), %g0 -14: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */ -15: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_getsockname), %g1 -16: lduwa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(sys_getsockname), %g0 -17: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */ -18: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_getpeername), %g1 -19: lduwa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(sys_getpeername), %g0 -20: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */ -21: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_socketpair), %g1 -22: ldswa [%o1 + 0x8] %asi, %o2 -23: lduwa [%o1 + 0xc] %asi, %o3 - jmpl %g1 + %lo(sys_socketpair), %g0 -24: ldswa [%o1 + 0x4] %asi, %o1 - nop - nop -do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */ -25: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_send), %g1 -26: lduwa [%o1 + 0x8] %asi, %o2 -27: lduwa [%o1 + 0xc] %asi, %o3 - jmpl %g1 + %lo(sys_send), %g0 -28: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop -do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */ -29: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_recv), %g1 -30: lduwa [%o1 + 0x8] %asi, %o2 -31: lduwa [%o1 + 0xc] %asi, %o3 - jmpl %g1 + %lo(sys_recv), %g0 -32: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop -do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ -33: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_sendto), %g1 -34: lduwa [%o1 + 0x8] %asi, %o2 -35: lduwa [%o1 + 0xc] %asi, %o3 -36: lduwa [%o1 + 0x10] %asi, %o4 -37: ldswa [%o1 + 0x14] %asi, %o5 - jmpl %g1 + %lo(sys_sendto), %g0 -38: lduwa [%o1 + 0x4] %asi, %o1 -do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ -39: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_recvfrom), %g1 -40: lduwa [%o1 + 0x8] %asi, %o2 -41: lduwa [%o1 + 0xc] %asi, %o3 -42: lduwa [%o1 + 0x10] %asi, %o4 -43: lduwa [%o1 + 0x14] %asi, %o5 - jmpl %g1 + %lo(sys_recvfrom), %g0 -44: lduwa [%o1 + 0x4] %asi, %o1 -do_sys_shutdown: /* sys_shutdown(int, int) */ -45: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_shutdown), %g1 - jmpl %g1 + %lo(sys_shutdown), %g0 -46: ldswa [%o1 + 0x4] %asi, %o1 - nop - nop - nop - nop -do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */ -47: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_setsockopt), %g1 -48: ldswa [%o1 + 0x8] %asi, %o2 -49: lduwa [%o1 + 0xc] %asi, %o3 -50: ldswa [%o1 + 0x10] %asi, %o4 - jmpl %g1 + %lo(sys_setsockopt), %g0 -51: ldswa [%o1 + 0x4] %asi, %o1 - nop -do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */ -52: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_getsockopt), %g1 -53: ldswa [%o1 + 0x8] %asi, %o2 -54: lduwa [%o1 + 0xc] %asi, %o3 -55: lduwa [%o1 + 0x10] %asi, %o4 - jmpl %g1 + %lo(sys_getsockopt), %g0 -56: ldswa [%o1 + 0x4] %asi, %o1 - nop -do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */ -57: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(compat_sys_sendmsg), %g1 -58: lduwa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(compat_sys_sendmsg), %g0 -59: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */ -60: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(compat_sys_recvmsg), %g1 -61: lduwa [%o1 + 0x8] %asi, %o2 - jmpl %g1 + %lo(compat_sys_recvmsg), %g0 -62: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - nop -do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */ -63: ldswa [%o1 + 0x0] %asi, %o0 - sethi %hi(sys_accept4), %g1 -64: lduwa [%o1 + 0x8] %asi, %o2 -65: ldswa [%o1 + 0xc] %asi, %o3 - jmpl %g1 + %lo(sys_accept4), %g0 -66: lduwa [%o1 + 0x4] %asi, %o1 - nop - nop - - .section __ex_table,"a" - .align 4 - .word 1b, __retl_efault, 2b, __retl_efault - .word 3b, __retl_efault, 4b, __retl_efault - .word 5b, __retl_efault, 6b, __retl_efault - .word 7b, __retl_efault, 8b, __retl_efault - .word 9b, __retl_efault, 10b, __retl_efault - .word 11b, __retl_efault, 12b, __retl_efault - .word 13b, __retl_efault, 14b, __retl_efault - .word 15b, __retl_efault, 16b, __retl_efault - .word 17b, __retl_efault, 18b, __retl_efault - .word 19b, __retl_efault, 20b, __retl_efault - .word 21b, __retl_efault, 22b, __retl_efault - .word 23b, __retl_efault, 24b, __retl_efault - .word 25b, __retl_efault, 26b, __retl_efault - .word 27b, __retl_efault, 28b, __retl_efault - .word 29b, __retl_efault, 30b, __retl_efault - .word 31b, __retl_efault, 32b, __retl_efault - .word 33b, __retl_efault, 34b, __retl_efault - .word 35b, __retl_efault, 36b, __retl_efault - .word 37b, __retl_efault, 38b, __retl_efault - .word 39b, __retl_efault, 40b, __retl_efault - .word 41b, __retl_efault, 42b, __retl_efault - .word 43b, __retl_efault, 44b, __retl_efault - .word 45b, __retl_efault, 46b, __retl_efault - .word 47b, __retl_efault, 48b, __retl_efault - .word 49b, __retl_efault, 50b, __retl_efault - .word 51b, __retl_efault, 52b, __retl_efault - .word 53b, __retl_efault, 54b, __retl_efault - .word 55b, __retl_efault, 56b, __retl_efault - .word 57b, __retl_efault, 58b, __retl_efault - .word 59b, __retl_efault, 60b, __retl_efault - .word 61b, __retl_efault, 62b, __retl_efault - .word 63b, __retl_efault, 64b, __retl_efault - .word 65b, __retl_efault, 66b, __retl_efault - .previous --- linux-xilinx-6.8.0.orig/arch/sparc/kernel/syscalls/syscall.tbl +++ linux-xilinx-6.8.0/arch/sparc/kernel/syscalls/syscall.tbl @@ -117,7 +117,7 @@ 90 common dup2 sys_dup2 91 32 setfsuid32 sys_setfsuid 92 common fcntl sys_fcntl compat_sys_fcntl -93 common select sys_select +93 common select sys_select compat_sys_select 94 32 setfsgid32 sys_setfsgid 95 common fsync sys_fsync 96 common setpriority sys_setpriority @@ -155,7 +155,7 @@ 123 32 fchown sys_fchown16 123 64 fchown sys_fchown 124 common fchmod sys_fchmod -125 common recvfrom sys_recvfrom +125 common recvfrom sys_recvfrom compat_sys_recvfrom 126 32 setreuid sys_setreuid16 126 64 setreuid sys_setreuid 127 32 setregid sys_setregid16 @@ -247,7 +247,7 @@ 204 32 readdir sys_old_readdir compat_sys_old_readdir 204 64 readdir sys_nis_syscall 205 common readahead sys_readahead compat_sys_readahead -206 common socketcall sys_socketcall sys32_socketcall +206 common socketcall sys_socketcall compat_sys_socketcall 207 common syslog sys_syslog 208 common lookup_dcookie sys_ni_syscall 209 common fadvise64 sys_fadvise64 compat_sys_fadvise64 @@ -461,7 +461,7 @@ 412 32 utimensat_time64 sys_utimensat sys_utimensat 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive --- linux-xilinx-6.8.0.orig/arch/sparc/lib/Makefile +++ linux-xilinx-6.8.0/arch/sparc/lib/Makefile @@ -14,7 +14,7 @@ lib-$(CONFIG_SPARC32) += copy_user.o locks.o lib-$(CONFIG_SPARC64) += atomic_64.o lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o -lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o +lib-$(CONFIG_SPARC32) += muldi3.o bitext.o lib-$(CONFIG_SPARC64) += multi3.o lib-$(CONFIG_SPARC64) += fls.o lib-$(CONFIG_SPARC64) += fls64.o @@ -51,5 +51,5 @@ lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o obj-$(CONFIG_SPARC64) += iomap.o -obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o +obj-$(CONFIG_SPARC32) += atomic32.o obj-$(CONFIG_SPARC64) += PeeCeeI.o --- linux-xilinx-6.8.0.orig/arch/sparc/mm/init_64.c +++ linux-xilinx-6.8.0/arch/sparc/mm/init_64.c @@ -1665,7 +1665,7 @@ if (pud_none(*pud)) return false; - if (pud_large(*pud)) + if (pud_leaf(*pud)) return pfn_valid(pud_pfn(*pud)); pmd = pmd_offset(pud, addr); --- linux-xilinx-6.8.0.orig/arch/sparc/mm/tlb.c +++ linux-xilinx-6.8.0/arch/sparc/mm/tlb.c @@ -249,6 +249,7 @@ { pmd_t old, entry; + VM_WARN_ON_ONCE(!pmd_present(*pmdp)); entry = __pmd(pmd_val(*pmdp) & ~_PAGE_VALID); old = pmdp_establish(vma, address, pmdp, entry); flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); --- linux-xilinx-6.8.0.orig/arch/sparc/net/bpf_jit_comp_64.c +++ linux-xilinx-6.8.0/arch/sparc/net/bpf_jit_comp_64.c @@ -1602,7 +1602,11 @@ bpf_flush_icache(header, (u8 *)header + header->size); if (!prog->is_func || extra_pass) { - bpf_jit_binary_lock_ro(header); + if (bpf_jit_binary_lock_ro(header)) { + bpf_jit_binary_free(header); + prog = orig_prog; + goto out_off; + } } else { jit_data->ctx = ctx; jit_data->image = image_ptr; --- linux-xilinx-6.8.0.orig/arch/sparc/vdso/vma.c +++ linux-xilinx-6.8.0/arch/sparc/vdso/vma.c @@ -449,9 +449,8 @@ unsigned long val; err = kstrtoul(s, 10, &val); - if (err) - return err; - vdso_enabled = val; - return 0; + if (!err) + vdso_enabled = val; + return 1; } __setup("vdso=", vdso_setup); --- linux-xilinx-6.8.0.orig/arch/um/drivers/line.c +++ linux-xilinx-6.8.0/arch/um/drivers/line.c @@ -676,24 +676,26 @@ goto cleanup; } - *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), - .fd = fd, + *winch = ((struct winch) { .fd = fd, .tty_fd = tty_fd, .pid = pid, .port = port, .stack = stack }); + spin_lock(&winch_handler_lock); + list_add(&winch->list, &winch_handlers); + spin_unlock(&winch_handler_lock); + if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, IRQF_SHARED, "winch", winch) < 0) { printk(KERN_ERR "register_winch_irq - failed to register " "IRQ\n"); + spin_lock(&winch_handler_lock); + list_del(&winch->list); + spin_unlock(&winch_handler_lock); goto out_free; } - spin_lock(&winch_handler_lock); - list_add(&winch->list, &winch_handlers); - spin_unlock(&winch_handler_lock); - return; out_free: --- linux-xilinx-6.8.0.orig/arch/um/drivers/ubd_kern.c +++ linux-xilinx-6.8.0/arch/um/drivers/ubd_kern.c @@ -1098,7 +1098,7 @@ if (irq_req_buffer == NULL) { printk(KERN_ERR "Failed to initialize ubd buffering\n"); - return -1; + return -ENOMEM; } io_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE, sizeof(struct io_thread_req *), @@ -1109,7 +1109,7 @@ if (io_req_buffer == NULL) { printk(KERN_ERR "Failed to initialize ubd buffering\n"); - return -1; + return -ENOMEM; } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); --- linux-xilinx-6.8.0.orig/arch/um/drivers/vector_kern.c +++ linux-xilinx-6.8.0/arch/um/drivers/vector_kern.c @@ -141,7 +141,7 @@ if (allow != NULL) { if (kstrtoul(allow, 10, &result) == 0) - return (allow > 0); + return result > 0; } return false; } --- linux-xilinx-6.8.0.orig/arch/um/include/asm/kasan.h +++ linux-xilinx-6.8.0/arch/um/include/asm/kasan.h @@ -24,7 +24,6 @@ #ifdef CONFIG_KASAN void kasan_init(void); -void kasan_map_memory(void *start, unsigned long len); extern int kasan_um_is_ready; #ifdef CONFIG_STATIC_LINK --- linux-xilinx-6.8.0.orig/arch/um/include/asm/mmu.h +++ linux-xilinx-6.8.0/arch/um/include/asm/mmu.h @@ -14,8 +14,6 @@ struct uml_arch_mm_context arch; } mm_context_t; -extern void __switch_mm(struct mm_id * mm_idp); - /* Avoid tangled inclusion with asm/ldt.h */ extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); extern void free_ldt(struct mm_context *mm); --- linux-xilinx-6.8.0.orig/arch/um/include/asm/processor-generic.h +++ linux-xilinx-6.8.0/arch/um/include/asm/processor-generic.h @@ -94,7 +94,6 @@ #define current_cpu_data boot_cpu_data #define cache_line_size() (boot_cpu_data.cache_alignment) -extern unsigned long get_thread_reg(int reg, jmp_buf *buf); #define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf) extern unsigned long __get_wchan(struct task_struct *p); --- linux-xilinx-6.8.0.orig/arch/um/include/shared/kern_util.h +++ linux-xilinx-6.8.0/arch/um/include/shared/kern_util.h @@ -66,4 +66,6 @@ void um_idle_sleep(void); +void kasan_map_memory(void *start, size_t len); + #endif --- linux-xilinx-6.8.0.orig/arch/um/include/shared/skas/mm_id.h +++ linux-xilinx-6.8.0/arch/um/include/shared/skas/mm_id.h @@ -15,4 +15,6 @@ int kill; }; +void __switch_mm(struct mm_id *mm_idp); + #endif --- linux-xilinx-6.8.0.orig/arch/um/os-Linux/mem.c +++ linux-xilinx-6.8.0/arch/um/os-Linux/mem.c @@ -15,6 +15,7 @@ #include #include #include +#include #include /* --- linux-xilinx-6.8.0.orig/arch/x86/Kconfig +++ linux-xilinx-6.8.0/arch/x86/Kconfig @@ -62,6 +62,7 @@ select ACPI_HOTPLUG_CPU if ACPI_PROCESSOR && HOTPLUG_CPU select ARCH_32BIT_OFF_T if X86_32 select ARCH_CLOCKSOURCE_INIT + select ARCH_CONFIGURES_CPU_MITIGATIONS select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE select ARCH_ENABLE_HUGEPAGE_MIGRATION if X86_64 && HUGETLB_PAGE && MIGRATION select ARCH_ENABLE_MEMORY_HOTPLUG if X86_64 @@ -100,7 +101,7 @@ select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE select ARCH_HAS_SYSCALL_WRAPPER - select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_UBSAN select ARCH_HAS_DEBUG_WX select ARCH_HAS_ZONE_DMA_SET if EXPERT select ARCH_HAVE_NMI_SAFE_CMPXCHG @@ -1539,19 +1540,6 @@ This requires an AMD processor that supports Secure Memory Encryption (SME). -config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT - bool "Activate AMD Secure Memory Encryption (SME) by default" - depends on AMD_MEM_ENCRYPT - help - Say yes to have system memory encrypted by default if running on - an AMD processor that supports Secure Memory Encryption (SME). - - If set to Y, then the encryption of system memory can be - deactivated with the mem_encrypt=off command line option. - - If set to N, then the encryption of system memory can be - activated with the mem_encrypt=on command line option. - # Common NUMA Features config NUMA bool "NUMA Memory Allocation and Scheduler Support" @@ -2480,17 +2468,21 @@ def_bool y depends on CALL_PADDING && !CFI_CLANG -menuconfig SPECULATION_MITIGATIONS - bool "Mitigations for speculative execution vulnerabilities" +menuconfig CPU_MITIGATIONS + bool "Mitigations for CPU vulnerabilities" default y help - Say Y here to enable options which enable mitigations for - speculative execution hardware vulnerabilities. + Say Y here to enable options which enable mitigations for hardware + vulnerabilities (usually related to speculative execution). + Mitigations can be disabled or restricted to SMT systems at runtime + via the "mitigations" kernel parameter. - If you say N, all mitigations will be disabled. You really - should know what you are doing to say so. + If you say N, all mitigations will be disabled. This CANNOT be + overridden at runtime. -if SPECULATION_MITIGATIONS + Say 'Y', unless you really know what you are doing. + +if CPU_MITIGATIONS config PAGE_TABLE_ISOLATION bool "Remove the kernel mapping in user mode" @@ -2614,6 +2606,27 @@ If in doubt, say N. +config MITIGATION_RFDS + bool "RFDS Mitigation" + depends on CPU_SUP_INTEL + default y + help + Enable mitigation for Register File Data Sampling (RFDS) by default. + RFDS is a hardware vulnerability which affects Intel Atom CPUs. It + allows unprivileged speculative access to stale data previously + stored in floating point, vector and integer registers. + See also + +config MITIGATION_SPECTRE_BHI + bool "Mitigate Spectre-BHB (Branch History Injection)" + depends on CPU_SUP_INTEL + default y + help + Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks + where the branch history buffer is poisoned to speculatively steer + indirect branches. + See + endif config ARCH_HAS_ADD_PAGES --- linux-xilinx-6.8.0.orig/arch/x86/Kconfig.debug +++ linux-xilinx-6.8.0/arch/x86/Kconfig.debug @@ -248,6 +248,7 @@ config UNWINDER_FRAME_POINTER bool "Frame pointer unwinder" + select ARCH_WANT_FRAME_POINTERS select FRAME_POINTER help This option enables the frame pointer unwinder for unwinding kernel @@ -271,7 +272,3 @@ overhead. endchoice - -config FRAME_POINTER - depends on !UNWINDER_ORC && !UNWINDER_GUESS - bool --- linux-xilinx-6.8.0.orig/arch/x86/boot/compressed/Makefile +++ linux-xilinx-6.8.0/arch/x86/boot/compressed/Makefile @@ -84,7 +84,7 @@ hostprogs := mkpiggy HOST_EXTRACFLAGS += -I$(srctree)/tools/include -sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p' +sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__start_rodata\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p' quiet_cmd_voffset = VOFFSET $@ cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ @@ -116,9 +116,9 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o -vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a +vmlinux-libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a -$(obj)/vmlinux: $(vmlinux-objs-y) FORCE +$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE $(call if_changed,ld) OBJCOPYFLAGS_vmlinux.bin := -R .comment -S --- linux-xilinx-6.8.0.orig/arch/x86/boot/compressed/efi_mixed.S +++ linux-xilinx-6.8.0/arch/x86/boot/compressed/efi_mixed.S @@ -15,10 +15,12 @@ */ #include +#include #include #include #include #include +#include .code64 .text @@ -49,6 +51,11 @@ lea efi32_boot_args(%rip), %rdx mov 0(%rdx), %edi mov 4(%rdx), %esi + + /* Switch to the firmware's stack */ + movl efi32_boot_sp(%rip), %esp + andl $~7, %esp + #ifdef CONFIG_EFI_HANDOVER_PROTOCOL mov 8(%rdx), %edx // saved bootparams pointer test %edx, %edx @@ -144,6 +151,7 @@ SYM_FUNC_START(efi32_stub_entry) call 1f 1: popl %ecx + leal (efi32_boot_args - 1b)(%ecx), %ebx /* Clear BSS */ xorl %eax, %eax @@ -158,6 +166,7 @@ popl %ecx popl %edx popl %esi + movl %esi, 8(%ebx) jmp efi32_entry SYM_FUNC_END(efi32_stub_entry) #endif @@ -234,8 +243,6 @@ * * Arguments: %ecx image handle * %edx EFI system table pointer - * %esi struct bootparams pointer (or NULL when not using - * the EFI handover protocol) * * Since this is the point of no return for ordinary execution, no registers * are considered live except for the function parameters. [Note that the EFI @@ -254,13 +261,25 @@ /* Store firmware IDT descriptor */ sidtl (efi32_boot_idt - 1b)(%ebx) + /* Store firmware stack pointer */ + movl %esp, (efi32_boot_sp - 1b)(%ebx) + /* Store boot arguments */ leal (efi32_boot_args - 1b)(%ebx), %ebx movl %ecx, 0(%ebx) movl %edx, 4(%ebx) - movl %esi, 8(%ebx) movb $0x0, 12(%ebx) // efi_is64 + /* + * Allocate some memory for a temporary struct boot_params, which only + * needs the minimal pieces that startup_32() relies on. + */ + subl $PARAM_SIZE, %esp + movl %esp, %esi + movl $PAGE_SIZE, BP_kernel_alignment(%esi) + movl $_end - 1b, BP_init_size(%esi) + subl $startup_32 - 1b, BP_init_size(%esi) + /* Disable paging */ movl %cr0, %eax btrl $X86_CR0_PG_BIT, %eax @@ -286,8 +305,7 @@ movl 8(%ebp), %ecx // image_handle movl 12(%ebp), %edx // sys_table - xorl %esi, %esi - jmp efi32_entry // pass %ecx, %edx, %esi + jmp efi32_entry // pass %ecx, %edx // no other registers remain live 2: popl %edi // restore callee-save registers @@ -318,5 +336,6 @@ SYM_DATA_LOCAL(efi32_boot_cs, .word 0) SYM_DATA_LOCAL(efi32_boot_ds, .word 0) +SYM_DATA_LOCAL(efi32_boot_sp, .long 0) SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) SYM_DATA(efi_is64, .byte 1) --- linux-xilinx-6.8.0.orig/arch/x86/boot/compressed/head_64.S +++ linux-xilinx-6.8.0/arch/x86/boot/compressed/head_64.S @@ -398,6 +398,11 @@ call sev_enable #endif + /* Preserve only the CR4 bits that must be preserved, and clear the rest */ + movq %cr4, %rax + andl $(X86_CR4_PAE | X86_CR4_MCE | X86_CR4_LA57), %eax + movq %rax, %cr4 + /* * configure_5level_paging() updates the number of paging levels using * a trampoline in 32-bit addressable memory if the current number does --- linux-xilinx-6.8.0.orig/arch/x86/boot/compressed/misc.c +++ linux-xilinx-6.8.0/arch/x86/boot/compressed/misc.c @@ -330,6 +330,7 @@ return ehdr.e_entry - LOAD_PHYSICAL_ADDR; } +const unsigned long kernel_text_size = VO___start_rodata - VO__text; const unsigned long kernel_total_size = VO__end - VO__text; static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4); @@ -358,6 +359,19 @@ } /* + * Set the memory encryption xloadflag based on the mem_encrypt= command line + * parameter, if provided. + */ +static void parse_mem_encrypt(struct setup_header *hdr) +{ + int on = cmdline_find_option_bool("mem_encrypt=on"); + int off = cmdline_find_option_bool("mem_encrypt=off"); + + if (on > off) + hdr->xloadflags |= XLF_MEM_ENCRYPTION; +} + +/* * The compressed kernel image (ZO), has been moved so that its position * is against the end of the buffer used to hold the uncompressed kernel * image (VO) and the execution environment (.bss, .brk), which makes sure @@ -387,6 +401,8 @@ /* Clear flags intended for solely in-kernel use. */ boot_params_ptr->hdr.loadflags &= ~KASLR_FLAG; + parse_mem_encrypt(&boot_params_ptr->hdr); + sanitize_boot_params(boot_params_ptr); if (boot_params_ptr->screen_info.orig_video_mode == 7) { --- linux-xilinx-6.8.0.orig/arch/x86/boot/compressed/sev.c +++ linux-xilinx-6.8.0/arch/x86/boot/compressed/sev.c @@ -116,6 +116,9 @@ #undef __init #define __init +#undef __head +#define __head + #define __BOOT_COMPRESSED /* Basic instruction decoding support needed */ @@ -304,6 +307,10 @@ if (result != ES_OK) goto finish; + result = vc_check_opcode_bytes(&ctxt, exit_code); + if (result != ES_OK) + goto finish; + switch (exit_code) { case SVM_EXIT_RDTSC: case SVM_EXIT_RDTSCP: --- linux-xilinx-6.8.0.orig/arch/x86/boot/main.c +++ linux-xilinx-6.8.0/arch/x86/boot/main.c @@ -119,8 +119,8 @@ char *stack_end; if (boot_params.hdr.loadflags & CAN_USE_HEAP) { - asm("leal %P1(%%esp),%0" - : "=r" (stack_end) : "i" (-STACK_SIZE)); + asm("leal %n1(%%esp),%0" + : "=r" (stack_end) : "i" (STACK_SIZE)); heap_end = (char *) ((size_t)boot_params.hdr.heap_end_ptr + 0x200); --- linux-xilinx-6.8.0.orig/arch/x86/coco/core.c +++ linux-xilinx-6.8.0/arch/x86/coco/core.c @@ -3,18 +3,22 @@ * Confidential Computing Platform Capability checks * * Copyright (C) 2021 Advanced Micro Devices, Inc. + * Copyright (C) 2024 Jason A. Donenfeld . All Rights Reserved. * * Author: Tom Lendacky */ #include #include +#include +#include +#include #include #include enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE; -static u64 cc_mask __ro_after_init; +u64 cc_mask __ro_after_init; static bool noinstr intel_cc_platform_has(enum cc_attr attr) { @@ -149,7 +153,39 @@ } EXPORT_SYMBOL_GPL(cc_mkdec); -__init void cc_set_mask(u64 mask) +__init void cc_random_init(void) { - cc_mask = mask; + /* + * The seed is 32 bytes (in units of longs), which is 256 bits, which + * is the security level that the RNG is targeting. + */ + unsigned long rng_seed[32 / sizeof(long)]; + size_t i, longs; + + if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) + return; + + /* + * Since the CoCo threat model includes the host, the only reliable + * source of entropy that can be neither observed nor manipulated is + * RDRAND. Usually, RDRAND failure is considered tolerable, but since + * CoCo guests have no other unobservable source of entropy, it's + * important to at least ensure the RNG gets some initial random seeds. + */ + for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) { + longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i); + + /* + * A zero return value means that the guest doesn't have RDRAND + * or the CPU is physically broken, and in both cases that + * means most crypto inside of the CoCo instance will be + * broken, defeating the purpose of CoCo in the first place. So + * just panic here because it's absolutely unsafe to continue + * executing. + */ + if (longs == 0) + panic("RDRAND is defective."); + } + add_device_randomness(rng_seed, sizeof(rng_seed)); + memzero_explicit(rng_seed, sizeof(rng_seed)); } --- linux-xilinx-6.8.0.orig/arch/x86/crypto/nh-avx2-x86_64.S +++ linux-xilinx-6.8.0/arch/x86/crypto/nh-avx2-x86_64.S @@ -154,5 +154,6 @@ vpaddq T1, T0, T0 vpaddq T4, T0, T0 vmovdqu T0, (HASH) + vzeroupper RET SYM_FUNC_END(nh_avx2) --- linux-xilinx-6.8.0.orig/arch/x86/crypto/sha256-avx2-asm.S +++ linux-xilinx-6.8.0/arch/x86/crypto/sha256-avx2-asm.S @@ -716,6 +716,7 @@ popq %r13 popq %r12 popq %rbx + vzeroupper RET SYM_FUNC_END(sha256_transform_rorx) --- linux-xilinx-6.8.0.orig/arch/x86/crypto/sha512-avx2-asm.S +++ linux-xilinx-6.8.0/arch/x86/crypto/sha512-avx2-asm.S @@ -680,6 +680,7 @@ pop %r12 pop %rbx + vzeroupper RET SYM_FUNC_END(sha512_transform_rorx) --- linux-xilinx-6.8.0.orig/arch/x86/entry/common.c +++ linux-xilinx-6.8.0/arch/x86/entry/common.c @@ -49,7 +49,7 @@ if (likely(unr < NR_syscalls)) { unr = array_index_nospec(unr, NR_syscalls); - regs->ax = sys_call_table[unr](regs); + regs->ax = x64_sys_call(regs, unr); return true; } return false; @@ -66,7 +66,7 @@ if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) { xnr = array_index_nospec(xnr, X32_NR_syscalls); - regs->ax = x32_sys_call_table[xnr](regs); + regs->ax = x32_sys_call(regs, xnr); return true; } return false; @@ -162,7 +162,7 @@ if (likely(unr < IA32_NR_syscalls)) { unr = array_index_nospec(unr, IA32_NR_syscalls); - regs->ax = ia32_sys_call_table[unr](regs); + regs->ax = ia32_sys_call(regs, unr); } else if (nr != -1) { regs->ax = __ia32_sys_ni_syscall(regs); } @@ -189,7 +189,7 @@ } /** - * int80_emulation - 32-bit legacy syscall entry + * do_int80_emulation - 32-bit legacy syscall C entry from asm * * This entry point can be used by 32-bit and 64-bit programs to perform * 32-bit system calls. Instances of INT $0x80 can be found inline in @@ -207,7 +207,7 @@ * eax: system call number * ebx, ecx, edx, esi, edi, ebp: arg1 - arg 6 */ -DEFINE_IDTENTRY_RAW(int80_emulation) +__visible noinstr void do_int80_emulation(struct pt_regs *regs) { int nr; --- linux-xilinx-6.8.0.orig/arch/x86/entry/entry_64.S +++ linux-xilinx-6.8.0/arch/x86/entry/entry_64.S @@ -116,6 +116,7 @@ /* clobbers %rax, make sure it is after saving the syscall nr */ IBRS_ENTER UNTRAIN_RET + CLEAR_BRANCH_HISTORY call do_syscall_64 /* returns with IRQs disabled */ @@ -1494,3 +1495,63 @@ call make_task_dead SYM_CODE_END(rewind_stack_and_make_dead) .popsection + +/* + * This sequence executes branches in order to remove user branch information + * from the branch history tracker in the Branch Predictor, therefore removing + * user influence on subsequent BTB lookups. + * + * It should be used on parts prior to Alder Lake. Newer parts should use the + * BHI_DIS_S hardware control instead. If a pre-Alder Lake part is being + * virtualized on newer hardware the VMM should protect against BHI attacks by + * setting BHI_DIS_S for the guests. + * + * CALLs/RETs are necessary to prevent Loop Stream Detector(LSD) from engaging + * and not clearing the branch history. The call tree looks like: + * + * call 1 + * call 2 + * call 2 + * call 2 + * call 2 + * call 2 + * ret + * ret + * ret + * ret + * ret + * ret + * + * This means that the stack is non-constant and ORC can't unwind it with %rsp + * alone. Therefore we unconditionally set up the frame pointer, which allows + * ORC to unwind properly. + * + * The alignment is for performance and not for safety, and may be safely + * refactored in the future if needed. + */ +SYM_FUNC_START(clear_bhb_loop) + push %rbp + mov %rsp, %rbp + movl $5, %ecx + ANNOTATE_INTRA_FUNCTION_CALL + call 1f + jmp 5f + .align 64, 0xcc + ANNOTATE_INTRA_FUNCTION_CALL +1: call 2f + RET + .align 64, 0xcc +2: movl $5, %eax +3: jmp 4f + nop +4: sub $1, %eax + jnz 3b + sub $1, %ecx + jnz 1b + RET +5: lfence + pop %rbp + RET +SYM_FUNC_END(clear_bhb_loop) +EXPORT_SYMBOL_GPL(clear_bhb_loop) +STACK_FRAME_NON_STANDARD(clear_bhb_loop) --- linux-xilinx-6.8.0.orig/arch/x86/entry/entry_64_compat.S +++ linux-xilinx-6.8.0/arch/x86/entry/entry_64_compat.S @@ -90,9 +90,6 @@ cld - IBRS_ENTER - UNTRAIN_RET - /* * SYSENTER doesn't filter flags, so we need to clear NT and AC * ourselves. To save a few cycles, we can check whether @@ -116,6 +113,16 @@ jnz .Lsysenter_fix_flags .Lsysenter_flags_fixed: + /* + * CPU bugs mitigations mechanisms can call other functions. They + * should be invoked after making sure TF is cleared because + * single-step is ignored only for instructions inside the + * entry_SYSENTER_compat function. + */ + IBRS_ENTER + UNTRAIN_RET + CLEAR_BRANCH_HISTORY + movq %rsp, %rdi call do_SYSENTER_32 jmp sysret32_from_system_call @@ -206,6 +213,7 @@ IBRS_ENTER UNTRAIN_RET + CLEAR_BRANCH_HISTORY movq %rsp, %rdi call do_fast_syscall_32 @@ -276,3 +284,17 @@ ANNOTATE_NOENDBR int3 SYM_CODE_END(entry_SYSCALL_compat) + +/* + * int 0x80 is used by 32 bit mode as a system call entry. Normally idt entries + * point to C routines, however since this is a system call interface the branch + * history needs to be scrubbed to protect against BHI attacks, and that + * scrubbing needs to take place in assembly code prior to entering any C + * routines. + */ +SYM_CODE_START(int80_emulation) + ANNOTATE_NOENDBR + UNWIND_HINT_FUNC + CLEAR_BRANCH_HISTORY + jmp do_int80_emulation +SYM_CODE_END(int80_emulation) --- linux-xilinx-6.8.0.orig/arch/x86/entry/syscall_32.c +++ linux-xilinx-6.8.0/arch/x86/entry/syscall_32.c @@ -18,8 +18,25 @@ #include #undef __SYSCALL +/* + * The sys_call_table[] is no longer used for system calls, but + * kernel/trace/trace_syscalls.c still wants to know the system + * call address. + */ +#ifdef CONFIG_X86_32 #define __SYSCALL(nr, sym) __ia32_##sym, - -__visible const sys_call_ptr_t ia32_sys_call_table[] = { +const sys_call_ptr_t sys_call_table[] = { #include }; +#undef __SYSCALL +#endif + +#define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs); + +long ia32_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include + default: return __ia32_sys_ni_syscall(regs); + } +}; --- linux-xilinx-6.8.0.orig/arch/x86/entry/syscall_64.c +++ linux-xilinx-6.8.0/arch/x86/entry/syscall_64.c @@ -11,8 +11,23 @@ #include #undef __SYSCALL +/* + * The sys_call_table[] is no longer used for system calls, but + * kernel/trace/trace_syscalls.c still wants to know the system + * call address. + */ #define __SYSCALL(nr, sym) __x64_##sym, - -asmlinkage const sys_call_ptr_t sys_call_table[] = { +const sys_call_ptr_t sys_call_table[] = { #include }; +#undef __SYSCALL + +#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs); + +long x64_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include + default: return __x64_sys_ni_syscall(regs); + } +}; --- linux-xilinx-6.8.0.orig/arch/x86/entry/syscall_x32.c +++ linux-xilinx-6.8.0/arch/x86/entry/syscall_x32.c @@ -11,8 +11,12 @@ #include #undef __SYSCALL -#define __SYSCALL(nr, sym) __x64_##sym, +#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs); -asmlinkage const sys_call_ptr_t x32_sys_call_table[] = { -#include +long x32_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include + default: return __x64_sys_ni_syscall(regs); + } }; --- linux-xilinx-6.8.0.orig/arch/x86/entry/syscalls/syscall_32.tbl +++ linux-xilinx-6.8.0/arch/x86/entry/syscalls/syscall_32.tbl @@ -420,7 +420,7 @@ 412 i386 utimensat_time64 sys_utimensat 413 i386 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 414 i386 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 -416 i386 io_pgetevents_time64 sys_io_pgetevents +416 i386 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 417 i386 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 418 i386 mq_timedsend_time64 sys_mq_timedsend 419 i386 mq_timedreceive_time64 sys_mq_timedreceive --- linux-xilinx-6.8.0.orig/arch/x86/entry/vdso/Makefile +++ linux-xilinx-6.8.0/arch/x86/entry/vdso/Makefile @@ -34,8 +34,13 @@ KASAN_SANITIZE_vma.o := y UBSAN_SANITIZE_vma.o := y KCSAN_SANITIZE_vma.o := y -OBJECT_FILES_NON_STANDARD_vma.o := n -OBJECT_FILES_NON_STANDARD_extable.o := n + +OBJECT_FILES_NON_STANDARD_extable.o := n +OBJECT_FILES_NON_STANDARD_vdso-image-32.o := n +OBJECT_FILES_NON_STANDARD_vdso-image-x32.o := n +OBJECT_FILES_NON_STANDARD_vdso-image-64.o := n +OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n +OBJECT_FILES_NON_STANDARD_vma.o := n # vDSO images to build vdso_img-$(VDSO64-y) += 64 @@ -43,7 +48,6 @@ vdso_img-$(VDSO32-y) += 32 obj-$(VDSO32-y) += vdso32-setup.o -OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n vobjs := $(foreach F,$(vobjs-y),$(obj)/$F) vobjs32 := $(foreach F,$(vobjs32-y),$(obj)/$F) --- linux-xilinx-6.8.0.orig/arch/x86/entry/vsyscall/vsyscall_64.c +++ linux-xilinx-6.8.0/arch/x86/entry/vsyscall/vsyscall_64.c @@ -98,11 +98,6 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) { - /* - * XXX: if access_ok, get_user, and put_user handled - * sig_on_uaccess_err, this could go away. - */ - if (!access_ok((void __user *)ptr, size)) { struct thread_struct *thread = ¤t->thread; @@ -120,10 +115,8 @@ bool emulate_vsyscall(unsigned long error_code, struct pt_regs *regs, unsigned long address) { - struct task_struct *tsk; unsigned long caller; int vsyscall_nr, syscall_nr, tmp; - int prev_sig_on_uaccess_err; long ret; unsigned long orig_dx; @@ -172,8 +165,6 @@ goto sigsegv; } - tsk = current; - /* * Check for access_ok violations and find the syscall nr. * @@ -234,12 +225,8 @@ goto do_ret; /* skip requested */ /* - * With a real vsyscall, page faults cause SIGSEGV. We want to - * preserve that behavior to make writing exploits harder. + * With a real vsyscall, page faults cause SIGSEGV. */ - prev_sig_on_uaccess_err = current->thread.sig_on_uaccess_err; - current->thread.sig_on_uaccess_err = 1; - ret = -EFAULT; switch (vsyscall_nr) { case 0: @@ -262,23 +249,12 @@ break; } - current->thread.sig_on_uaccess_err = prev_sig_on_uaccess_err; - check_fault: if (ret == -EFAULT) { /* Bad news -- userspace fed a bad pointer to a vsyscall. */ warn_bad_vsyscall(KERN_INFO, regs, "vsyscall fault (exploit attempt?)"); - - /* - * If we failed to generate a signal for any reason, - * generate one here. (This should be impossible.) - */ - if (WARN_ON_ONCE(!sigismember(&tsk->pending.signal, SIGBUS) && - !sigismember(&tsk->pending.signal, SIGSEGV))) - goto sigsegv; - - return true; /* Don't emulate the ret. */ + goto sigsegv; } regs->ax = ret; --- linux-xilinx-6.8.0.orig/arch/x86/events/amd/core.c +++ linux-xilinx-6.8.0/arch/x86/events/amd/core.c @@ -250,7 +250,7 @@ /* * AMD Performance Monitor Family 17h and later: */ -static const u64 amd_f17h_perfmon_event_map[PERF_COUNT_HW_MAX] = +static const u64 amd_zen1_perfmon_event_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, @@ -262,10 +262,24 @@ [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x0187, }; +static const u64 amd_zen2_perfmon_event_map[PERF_COUNT_HW_MAX] = +{ + [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60, + [PERF_COUNT_HW_CACHE_MISSES] = 0x0964, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a9, +}; + static u64 amd_pmu_event_map(int hw_event) { - if (boot_cpu_data.x86 >= 0x17) - return amd_f17h_perfmon_event_map[hw_event]; + if (cpu_feature_enabled(X86_FEATURE_ZEN2) || boot_cpu_data.x86 >= 0x19) + return amd_zen2_perfmon_event_map[hw_event]; + + if (cpu_feature_enabled(X86_FEATURE_ZEN1)) + return amd_zen1_perfmon_event_map[hw_event]; return amd_perfmon_event_map[hw_event]; } @@ -604,7 +618,6 @@ kfree(cpuhw->lbr_sel); cpuhw->lbr_sel = NULL; - amd_pmu_cpu_reset(cpu); if (!x86_pmu.amd_nb_constraints) return; --- linux-xilinx-6.8.0.orig/arch/x86/events/amd/lbr.c +++ linux-xilinx-6.8.0/arch/x86/events/amd/lbr.c @@ -173,9 +173,11 @@ /* * Check if a branch has been logged; if valid = 0, spec = 0 - * then no branch was recorded + * then no branch was recorded; if reserved = 1 then an + * erroneous branch was recorded (see Erratum 1452) */ - if (!entry.to.split.valid && !entry.to.split.spec) + if ((!entry.to.split.valid && !entry.to.split.spec) || + entry.to.split.reserved) continue; perf_clear_branch_entry_bitfields(br + out); --- linux-xilinx-6.8.0.orig/arch/x86/events/core.c +++ linux-xilinx-6.8.0/arch/x86/events/core.c @@ -1644,6 +1644,7 @@ while (++i < cpuc->n_events) { cpuc->event_list[i-1] = cpuc->event_list[i]; cpuc->event_constraint[i-1] = cpuc->event_constraint[i]; + cpuc->assign[i-1] = cpuc->assign[i]; } cpuc->event_constraint[i-1] = NULL; --cpuc->n_events; --- linux-xilinx-6.8.0.orig/arch/x86/events/intel/ds.c +++ linux-xilinx-6.8.0/arch/x86/events/intel/ds.c @@ -1236,11 +1236,11 @@ struct pmu *pmu = event->pmu; /* - * Make sure we get updated with the first PEBS - * event. It will trigger also during removal, but - * that does not hurt: + * Make sure we get updated with the first PEBS event. + * During removal, ->pebs_data_cfg is still valid for + * the last PEBS event. Don't clear it. */ - if (cpuc->n_pebs == 1) + if ((cpuc->n_pebs == 1) && add) cpuc->pebs_data_cfg = PEBS_UPDATE_DS_SW; if (needed_cb != pebs_needs_sched_cb(cpuc)) { --- linux-xilinx-6.8.0.orig/arch/x86/hyperv/hv_vtl.c +++ linux-xilinx-6.8.0/arch/x86/hyperv/hv_vtl.c @@ -12,6 +12,7 @@ #include #include #include +#include <../kernel/smpboot.h> extern struct boot_params boot_params; static struct real_mode_header hv_vtl_real_mode_header; @@ -64,7 +65,7 @@ ((secondary_startup_64_fn)secondary_startup_64)(&boot_params, &boot_params); } -static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored) +static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) { u64 status; int ret = 0; @@ -78,7 +79,9 @@ struct ldttss_desc *ldt; struct desc_struct *gdt; - u64 rsp = current->thread.sp; + struct task_struct *idle = idle_thread_get(cpu); + u64 rsp = (unsigned long)idle->thread.sp; + u64 rip = (u64)&hv_vtl_ap_entry; native_store_gdt(&gdt_ptr); @@ -205,7 +208,15 @@ static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip) { - int vp_id; + int vp_id, cpu; + + /* Find the logical CPU for the APIC ID */ + for_each_present_cpu(cpu) { + if (arch_match_cpu_phys_id(cpu, apicid)) + break; + } + if (cpu >= nr_cpu_ids) + return -EINVAL; pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid); vp_id = hv_vtl_apicid_to_vp_id(apicid); @@ -219,7 +230,7 @@ return -EINVAL; } - return hv_vtl_bringup_vcpu(vp_id, start_eip); + return hv_vtl_bringup_vcpu(vp_id, cpu, start_eip); } int __init hv_vtl_early_init(void) --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/alternative.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/alternative.h @@ -294,10 +294,10 @@ * Otherwise, if CPU has feature1, newinstr1 is used. * Otherwise, oldinstr is used. */ -#define alternative_input_2(oldinstr, newinstr1, ft_flags1, newinstr2, \ - ft_flags2, input...) \ - asm_inline volatile(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, \ - newinstr2, ft_flags2) \ +#define alternative_input_2(oldinstr, newinstr1, ft_flags1, newinstr2, \ + ft_flags2, input...) \ + asm_inline volatile(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, \ + newinstr2, ft_flags2) \ : : "i" (0), ## input) /* Like alternative_input, but with a single output argument */ @@ -307,7 +307,7 @@ /* Like alternative_io, but for replacing a direct call with another one. */ #define alternative_call(oldfunc, newfunc, ft_flags, output, input...) \ - asm_inline volatile (ALTERNATIVE("call %P[old]", "call %P[new]", ft_flags) \ + asm_inline volatile (ALTERNATIVE("call %c[old]", "call %c[new]", ft_flags) \ : output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input) /* @@ -316,12 +316,12 @@ * Otherwise, if CPU has feature1, function1 is used. * Otherwise, old function is used. */ -#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2, \ - output, input...) \ - asm_inline volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", ft_flags1,\ - "call %P[new2]", ft_flags2) \ - : output, ASM_CALL_CONSTRAINT \ - : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ +#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2, \ + output, input...) \ + asm_inline volatile (ALTERNATIVE_2("call %c[old]", "call %c[new1]", ft_flags1, \ + "call %c[new2]", ft_flags2) \ + : output, ASM_CALL_CONSTRAINT \ + : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ [new2] "i" (newfunc2), ## input) /* --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/apic.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/apic.h @@ -13,6 +13,7 @@ #include #include #include +#include #define ARCH_APICTIMER_STOPS_ON_C3 1 @@ -96,7 +97,7 @@ static inline u32 native_apic_mem_read(u32 reg) { - return *((volatile u32 *)(APIC_BASE + reg)); + return readl((void __iomem *)(APIC_BASE + reg)); } static inline void native_apic_mem_eoi(void) --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/asm-prototypes.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/asm-prototypes.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifndef CONFIG_X86_CMPXCHG64 extern void cmpxchg8b_emu(void); --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/asm.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/asm.h @@ -113,6 +113,20 @@ #endif +#ifndef __ASSEMBLY__ +#ifndef __pic__ +static __always_inline __pure void *rip_rel_ptr(void *p) +{ + asm("leaq %c1(%%rip), %0" : "=r"(p) : "i"(p)); + + return p; +} +#define RIP_REL_REF(var) (*(typeof(&(var)))rip_rel_ptr(&(var))) +#else +#define RIP_REL_REF(var) (var) +#endif +#endif + /* * Macros to generate condition code outputs from inline assembly, * The output operand must be type "bool". --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/atomic64_32.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/atomic64_32.h @@ -24,7 +24,7 @@ #ifdef CONFIG_X86_CMPXCHG64 #define __alternative_atomic64(f, g, out, in...) \ - asm volatile("call %P[func]" \ + asm volatile("call %c[func]" \ : out : [func] "i" (atomic64_##g##_cx8), ## in) #define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8) --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/barrier.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/barrier.h @@ -79,6 +79,9 @@ #define __smp_mb__before_atomic() do { } while (0) #define __smp_mb__after_atomic() do { } while (0) +/* Writing to CR3 provides a full memory barrier in switch_mm(). */ +#define smp_mb__after_switch_mm() do { } while (0) + #include #endif /* _ASM_X86_BARRIER_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/boot.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/boot.h @@ -81,6 +81,7 @@ #ifndef __ASSEMBLY__ extern unsigned int output_len; +extern const unsigned long kernel_text_size; extern const unsigned long kernel_total_size; unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr, --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/cmpxchg_64.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/cmpxchg_64.h @@ -62,7 +62,7 @@ asm volatile(_lock "cmpxchg16b %[ptr]" \ CC_SET(e) \ : CC_OUT(e) (ret), \ - [ptr] "+m" (*ptr), \ + [ptr] "+m" (*(_ptr)), \ "+a" (o.low), "+d" (o.high) \ : "b" (n.low), "c" (n.high) \ : "memory"); \ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/coco.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/coco.h @@ -2,6 +2,7 @@ #ifndef _ASM_X86_COCO_H #define _ASM_X86_COCO_H +#include #include enum cc_vendor { @@ -12,11 +13,18 @@ #ifdef CONFIG_ARCH_HAS_CC_PLATFORM extern enum cc_vendor cc_vendor; -void cc_set_mask(u64 mask); +extern u64 cc_mask; +static inline void cc_set_mask(u64 mask) +{ + RIP_REL_REF(cc_mask) = mask; +} + u64 cc_mkenc(u64 val); u64 cc_mkdec(u64 val); +void cc_random_init(void); #else #define cc_vendor (CC_VENDOR_NONE) +static const u64 cc_mask = 0; static inline u64 cc_mkenc(u64 val) { @@ -27,6 +35,7 @@ { return val; } +static inline void cc_random_init(void) { } #endif #endif /* _ASM_X86_COCO_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/cpu_device_id.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/cpu_device_id.h @@ -3,6 +3,39 @@ #define _ASM_X86_CPU_DEVICE_ID /* + * Can't use because it generates expressions that + * cannot be used in structure initializers. Bitfield construction + * here must match the union in struct cpuinfo_86: + * union { + * struct { + * __u8 x86_model; + * __u8 x86; + * __u8 x86_vendor; + * __u8 x86_reserved; + * }; + * __u32 x86_vfm; + * }; + */ +#define VFM_MODEL_BIT 0 +#define VFM_FAMILY_BIT 8 +#define VFM_VENDOR_BIT 16 +#define VFM_RSVD_BIT 24 + +#define VFM_MODEL_MASK GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT) +#define VFM_FAMILY_MASK GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT) +#define VFM_VENDOR_MASK GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT) + +#define VFM_MODEL(vfm) (((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT) +#define VFM_FAMILY(vfm) (((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT) +#define VFM_VENDOR(vfm) (((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT) + +#define VFM_MAKE(_vendor, _family, _model) ( \ + ((_model) << VFM_MODEL_BIT) | \ + ((_family) << VFM_FAMILY_BIT) | \ + ((_vendor) << VFM_VENDOR_BIT) \ +) + +/* * Declare drivers belonging to specific x86 CPUs * Similar in spirit to pci_device_id and related PCI functions * @@ -20,6 +53,9 @@ #define X86_CENTAUR_FAM6_C7_D 0xd #define X86_CENTAUR_FAM6_NANO 0xf +/* x86_cpu_id::flags */ +#define X86_CPU_ID_FLAG_ENTRY_VALID BIT(0) + #define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) /** * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching @@ -46,6 +82,18 @@ .model = _model, \ .steppings = _steppings, \ .feature = _feature, \ + .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ + .driver_data = (unsigned long) _data \ +} + +#define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ + _steppings, _feature, _data) { \ + .vendor = _vendor, \ + .family = _family, \ + .model = _model, \ + .steppings = _steppings, \ + .feature = _feature, \ + .flags = X86_CPU_ID_FLAG_ENTRY_VALID, \ .driver_data = (unsigned long) _data \ } @@ -164,6 +212,56 @@ X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ steppings, X86_FEATURE_ANY, data) +/** + * X86_MATCH_VFM - Match encoded vendor/family/model + * @vfm: Encoded 8-bits each for vendor, family, model + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is cast to unsigned long internally. + * + * Stepping and feature are set to wildcards + */ +#define X86_MATCH_VFM(vfm, data) \ + X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ + VFM_VENDOR(vfm), \ + VFM_FAMILY(vfm), \ + VFM_MODEL(vfm), \ + X86_STEPPING_ANY, X86_FEATURE_ANY, data) + +/** + * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping + * @vfm: Encoded 8-bits each for vendor, family, model + * @steppings: Bitmask of steppings to match + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is cast to unsigned long internally. + * + * feature is set to wildcard + */ +#define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data) \ + X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ + VFM_VENDOR(vfm), \ + VFM_FAMILY(vfm), \ + VFM_MODEL(vfm), \ + steppings, X86_FEATURE_ANY, data) + +/** + * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature + * @vfm: Encoded 8-bits each for vendor, family, model + * @feature: A X86_FEATURE bit + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is cast to unsigned long internally. + * + * Steppings is set to wildcard + */ +#define X86_MATCH_VFM_FEATURE(vfm, feature, data) \ + X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE( \ + VFM_VENDOR(vfm), \ + VFM_FAMILY(vfm), \ + VFM_MODEL(vfm), \ + X86_STEPPING_ANY, feature, data) + /* * Match specific microcode revisions. * @@ -188,6 +286,14 @@ .x86_model = (model), \ .x86_stepping = (stepping), \ .x86_microcode_rev = (revision), \ +} + +#define AMD_CPU_DESC(fam, model, stepping, revision) { \ + .x86_family = (fam), \ + .x86_vendor = X86_VENDOR_AMD, \ + .x86_model = (model), \ + .x86_stepping = (stepping), \ + .x86_microcode_rev = (revision), \ } extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match); --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/cpufeature.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/cpufeature.h @@ -33,6 +33,8 @@ CPUID_7_EDX, CPUID_8000_001F_EAX, CPUID_8000_0021_EAX, + CPUID_LNX_5, + NR_CPUID_WORDS, }; #define X86_CAP_FMT_NUM "%d:%d" @@ -91,8 +93,9 @@ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \ REQUIRED_MASK_CHECK || \ - BUILD_BUG_ON_ZERO(NCAPINTS != 21)) + BUILD_BUG_ON_ZERO(NCAPINTS != 22)) #define DISABLED_MASK_BIT_SET(feature_bit) \ ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \ @@ -116,8 +119,9 @@ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \ DISABLED_MASK_CHECK || \ - BUILD_BUG_ON_ZERO(NCAPINTS != 21)) + BUILD_BUG_ON_ZERO(NCAPINTS != 22)) #define cpu_has(c, bit) \ (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ @@ -169,7 +173,7 @@ static __always_inline bool _static_cpu_has(u16 bit) { asm goto( - ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]") + ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]") ".pushsection .altinstr_aux,\"ax\"\n" "6:\n" " testb %[bitnum]," _ASM_RIP(%P[cap_byte]) "\n" --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/cpufeatures.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/cpufeatures.h @@ -13,7 +13,7 @@ /* * Defines x86 CPU feature bits */ -#define NCAPINTS 21 /* N 32-bit words worth of info */ +#define NCAPINTS 22 /* N 32-bit words worth of info */ #define NBUGINTS 2 /* N 32-bit bug flags */ /* @@ -457,6 +457,17 @@ #define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */ /* + * Extended auxiliary flags: Linux defined - for features scattered in various + * CPUID levels like 0x80000022, etc and Linux defined features. + * + * Reuse free bits when adding new feature flags! + */ +#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */ +#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */ +#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */ +#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */ + +/* * BUG word(s) */ #define X86_BUG(x) (NCAPINTS*32 + (x)) @@ -503,4 +514,6 @@ /* BUG word 2 */ #define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */ +#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */ +#define X86_BUG_BHI X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */ #endif /* _ASM_X86_CPUFEATURES_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/crash_core.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/crash_core.h @@ -39,4 +39,6 @@ #endif } +#define HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY + #endif /* _X86_CRASH_CORE_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/disabled-features.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/disabled-features.h @@ -143,6 +143,7 @@ #define DISABLED_MASK18 (DISABLE_IBT) #define DISABLED_MASK19 0 #define DISABLED_MASK20 0 -#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21) +#define DISABLED_MASK21 0 +#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22) #endif /* _ASM_X86_DISABLED_FEATURES_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/efi.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/efi.h @@ -410,7 +410,6 @@ struct efi_memory_map_data *data); extern void __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags); -#define __efi_memmap_free __efi_memmap_free extern int __init efi_memmap_install(struct efi_memory_map_data *data); extern int __init efi_memmap_split_count(efi_memory_desc_t *md, --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/entry-common.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/entry-common.h @@ -73,19 +73,16 @@ #endif /* - * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), - * but not enough for x86 stack utilization comfort. To keep - * reasonable stack head room, reduce the maximum offset to 8 bits. - * - * The actual entropy will be further reduced by the compiler when - * applying stack alignment constraints (see cc_stack_align4/8 in + * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 + * bits. The actual entropy will be further reduced by the compiler + * when applying stack alignment constraints (see cc_stack_align4/8 in * arch/x86/Makefile), which will remove the 3 (x86_64) or 2 (ia32) * low bits from any entropy chosen here. * - * Therefore, final stack offset entropy will be 5 (x86_64) or - * 6 (ia32) bits. + * Therefore, final stack offset entropy will be 7 (x86_64) or + * 8 (ia32) bits. */ - choose_random_kstack_offset(rdtsc() & 0xFF); + choose_random_kstack_offset(rdtsc()); } #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/intel-family.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/intel-family.h @@ -40,136 +40,221 @@ * their own names :-( */ +#define IFM(_fam, _model) VFM_MAKE(X86_VENDOR_INTEL, _fam, _model) + /* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */ #define INTEL_FAM6_ANY X86_MODEL_ANY +/* Wildcard match for FAM6 so X86_MATCH_VFM(ANY) works */ +#define INTEL_ANY IFM(X86_FAMILY_ANY, X86_MODEL_ANY) #define INTEL_FAM6_CORE_YONAH 0x0E +#define INTEL_CORE_YONAH IFM(6, 0x0E) #define INTEL_FAM6_CORE2_MEROM 0x0F +#define INTEL_CORE2_MEROM IFM(6, 0x0F) #define INTEL_FAM6_CORE2_MEROM_L 0x16 +#define INTEL_CORE2_MEROM_L IFM(6, 0x16) #define INTEL_FAM6_CORE2_PENRYN 0x17 +#define INTEL_CORE2_PENRYN IFM(6, 0x17) #define INTEL_FAM6_CORE2_DUNNINGTON 0x1D +#define INTEL_CORE2_DUNNINGTON IFM(6, 0x1D) #define INTEL_FAM6_NEHALEM 0x1E +#define INTEL_NEHALEM IFM(6, 0x1E) #define INTEL_FAM6_NEHALEM_G 0x1F /* Auburndale / Havendale */ +#define INTEL_NEHALEM_G IFM(6, 0x1F) /* Auburndale / Havendale */ #define INTEL_FAM6_NEHALEM_EP 0x1A +#define INTEL_NEHALEM_EP IFM(6, 0x1A) #define INTEL_FAM6_NEHALEM_EX 0x2E +#define INTEL_NEHALEM_EX IFM(6, 0x2E) #define INTEL_FAM6_WESTMERE 0x25 +#define INTEL_WESTMERE IFM(6, 0x25) #define INTEL_FAM6_WESTMERE_EP 0x2C +#define INTEL_WESTMERE_EP IFM(6, 0x2C) #define INTEL_FAM6_WESTMERE_EX 0x2F +#define INTEL_WESTMERE_EX IFM(6, 0x2F) #define INTEL_FAM6_SANDYBRIDGE 0x2A +#define INTEL_SANDYBRIDGE IFM(6, 0x2A) #define INTEL_FAM6_SANDYBRIDGE_X 0x2D +#define INTEL_SANDYBRIDGE_X IFM(6, 0x2D) #define INTEL_FAM6_IVYBRIDGE 0x3A +#define INTEL_IVYBRIDGE IFM(6, 0x3A) #define INTEL_FAM6_IVYBRIDGE_X 0x3E +#define INTEL_IVYBRIDGE_X IFM(6, 0x3E) #define INTEL_FAM6_HASWELL 0x3C +#define INTEL_HASWELL IFM(6, 0x3C) #define INTEL_FAM6_HASWELL_X 0x3F +#define INTEL_HASWELL_X IFM(6, 0x3F) #define INTEL_FAM6_HASWELL_L 0x45 +#define INTEL_HASWELL_L IFM(6, 0x45) #define INTEL_FAM6_HASWELL_G 0x46 +#define INTEL_HASWELL_G IFM(6, 0x46) #define INTEL_FAM6_BROADWELL 0x3D +#define INTEL_BROADWELL IFM(6, 0x3D) #define INTEL_FAM6_BROADWELL_G 0x47 +#define INTEL_BROADWELL_G IFM(6, 0x47) #define INTEL_FAM6_BROADWELL_X 0x4F +#define INTEL_BROADWELL_X IFM(6, 0x4F) #define INTEL_FAM6_BROADWELL_D 0x56 +#define INTEL_BROADWELL_D IFM(6, 0x56) #define INTEL_FAM6_SKYLAKE_L 0x4E /* Sky Lake */ +#define INTEL_SKYLAKE_L IFM(6, 0x4E) /* Sky Lake */ #define INTEL_FAM6_SKYLAKE 0x5E /* Sky Lake */ +#define INTEL_SKYLAKE IFM(6, 0x5E) /* Sky Lake */ #define INTEL_FAM6_SKYLAKE_X 0x55 /* Sky Lake */ +#define INTEL_SKYLAKE_X IFM(6, 0x55) /* Sky Lake */ /* CASCADELAKE_X 0x55 Sky Lake -- s: 7 */ /* COOPERLAKE_X 0x55 Sky Lake -- s: 11 */ #define INTEL_FAM6_KABYLAKE_L 0x8E /* Sky Lake */ +#define INTEL_KABYLAKE_L IFM(6, 0x8E) /* Sky Lake */ /* AMBERLAKE_L 0x8E Sky Lake -- s: 9 */ /* COFFEELAKE_L 0x8E Sky Lake -- s: 10 */ /* WHISKEYLAKE_L 0x8E Sky Lake -- s: 11,12 */ #define INTEL_FAM6_KABYLAKE 0x9E /* Sky Lake */ +#define INTEL_KABYLAKE IFM(6, 0x9E) /* Sky Lake */ /* COFFEELAKE 0x9E Sky Lake -- s: 10-13 */ #define INTEL_FAM6_COMETLAKE 0xA5 /* Sky Lake */ +#define INTEL_COMETLAKE IFM(6, 0xA5) /* Sky Lake */ #define INTEL_FAM6_COMETLAKE_L 0xA6 /* Sky Lake */ +#define INTEL_COMETLAKE_L IFM(6, 0xA6) /* Sky Lake */ #define INTEL_FAM6_CANNONLAKE_L 0x66 /* Palm Cove */ +#define INTEL_CANNONLAKE_L IFM(6, 0x66) /* Palm Cove */ #define INTEL_FAM6_ICELAKE_X 0x6A /* Sunny Cove */ +#define INTEL_ICELAKE_X IFM(6, 0x6A) /* Sunny Cove */ #define INTEL_FAM6_ICELAKE_D 0x6C /* Sunny Cove */ +#define INTEL_ICELAKE_D IFM(6, 0x6C) /* Sunny Cove */ #define INTEL_FAM6_ICELAKE 0x7D /* Sunny Cove */ +#define INTEL_ICELAKE IFM(6, 0x7D) /* Sunny Cove */ #define INTEL_FAM6_ICELAKE_L 0x7E /* Sunny Cove */ +#define INTEL_ICELAKE_L IFM(6, 0x7E) /* Sunny Cove */ #define INTEL_FAM6_ICELAKE_NNPI 0x9D /* Sunny Cove */ +#define INTEL_ICELAKE_NNPI IFM(6, 0x9D) /* Sunny Cove */ #define INTEL_FAM6_ROCKETLAKE 0xA7 /* Cypress Cove */ +#define INTEL_ROCKETLAKE IFM(6, 0xA7) /* Cypress Cove */ #define INTEL_FAM6_TIGERLAKE_L 0x8C /* Willow Cove */ +#define INTEL_TIGERLAKE_L IFM(6, 0x8C) /* Willow Cove */ #define INTEL_FAM6_TIGERLAKE 0x8D /* Willow Cove */ +#define INTEL_TIGERLAKE IFM(6, 0x8D) /* Willow Cove */ #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Golden Cove */ +#define INTEL_SAPPHIRERAPIDS_X IFM(6, 0x8F) /* Golden Cove */ #define INTEL_FAM6_EMERALDRAPIDS_X 0xCF +#define INTEL_EMERALDRAPIDS_X IFM(6, 0xCF) #define INTEL_FAM6_GRANITERAPIDS_X 0xAD +#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) #define INTEL_FAM6_GRANITERAPIDS_D 0xAE +#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE) /* "Hybrid" Processors (P-Core/E-Core) */ #define INTEL_FAM6_LAKEFIELD 0x8A /* Sunny Cove / Tremont */ +#define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */ #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ +#define INTEL_ALDERLAKE IFM(6, 0x97) /* Golden Cove / Gracemont */ #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ +#define INTEL_ALDERLAKE_L IFM(6, 0x9A) /* Golden Cove / Gracemont */ #define INTEL_FAM6_RAPTORLAKE 0xB7 /* Raptor Cove / Enhanced Gracemont */ +#define INTEL_RAPTORLAKE IFM(6, 0xB7) /* Raptor Cove / Enhanced Gracemont */ #define INTEL_FAM6_RAPTORLAKE_P 0xBA +#define INTEL_RAPTORLAKE_P IFM(6, 0xBA) #define INTEL_FAM6_RAPTORLAKE_S 0xBF +#define INTEL_RAPTORLAKE_S IFM(6, 0xBF) #define INTEL_FAM6_METEORLAKE 0xAC +#define INTEL_METEORLAKE IFM(6, 0xAC) #define INTEL_FAM6_METEORLAKE_L 0xAA +#define INTEL_METEORLAKE_L IFM(6, 0xAA) #define INTEL_FAM6_ARROWLAKE_H 0xC5 +#define INTEL_ARROWLAKE_H IFM(6, 0xC5) #define INTEL_FAM6_ARROWLAKE 0xC6 +#define INTEL_ARROWLAKE IFM(6, 0xC6) +#define INTEL_FAM6_ARROWLAKE_U 0xB5 +#define INTEL_ARROWLAKE_U IFM(6, 0xB5) #define INTEL_FAM6_LUNARLAKE_M 0xBD +#define INTEL_LUNARLAKE_M IFM(6, 0xBD) /* "Small Core" Processors (Atom/E-Core) */ #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ +#define INTEL_ATOM_BONNELL IFM(6, 0x1C) /* Diamondville, Pineview */ #define INTEL_FAM6_ATOM_BONNELL_MID 0x26 /* Silverthorne, Lincroft */ +#define INTEL_ATOM_BONNELL_MID IFM(6, 0x26) /* Silverthorne, Lincroft */ #define INTEL_FAM6_ATOM_SALTWELL 0x36 /* Cedarview */ +#define INTEL_ATOM_SALTWELL IFM(6, 0x36) /* Cedarview */ #define INTEL_FAM6_ATOM_SALTWELL_MID 0x27 /* Penwell */ +#define INTEL_ATOM_SALTWELL_MID IFM(6, 0x27) /* Penwell */ #define INTEL_FAM6_ATOM_SALTWELL_TABLET 0x35 /* Cloverview */ +#define INTEL_ATOM_SALTWELL_TABLET IFM(6, 0x35) /* Cloverview */ #define INTEL_FAM6_ATOM_SILVERMONT 0x37 /* Bay Trail, Valleyview */ +#define INTEL_ATOM_SILVERMONT IFM(6, 0x37) /* Bay Trail, Valleyview */ #define INTEL_FAM6_ATOM_SILVERMONT_D 0x4D /* Avaton, Rangely */ +#define INTEL_ATOM_SILVERMONT_D IFM(6, 0x4D) /* Avaton, Rangely */ #define INTEL_FAM6_ATOM_SILVERMONT_MID 0x4A /* Merriefield */ +#define INTEL_ATOM_SILVERMONT_MID IFM(6, 0x4A) /* Merriefield */ #define INTEL_FAM6_ATOM_AIRMONT 0x4C /* Cherry Trail, Braswell */ +#define INTEL_ATOM_AIRMONT IFM(6, 0x4C) /* Cherry Trail, Braswell */ #define INTEL_FAM6_ATOM_AIRMONT_MID 0x5A /* Moorefield */ +#define INTEL_ATOM_AIRMONT_MID IFM(6, 0x5A) /* Moorefield */ #define INTEL_FAM6_ATOM_AIRMONT_NP 0x75 /* Lightning Mountain */ +#define INTEL_ATOM_AIRMONT_NP IFM(6, 0x75) /* Lightning Mountain */ #define INTEL_FAM6_ATOM_GOLDMONT 0x5C /* Apollo Lake */ +#define INTEL_ATOM_GOLDMONT IFM(6, 0x5C) /* Apollo Lake */ #define INTEL_FAM6_ATOM_GOLDMONT_D 0x5F /* Denverton */ +#define INTEL_ATOM_GOLDMONT_D IFM(6, 0x5F) /* Denverton */ /* Note: the micro-architecture is "Goldmont Plus" */ #define INTEL_FAM6_ATOM_GOLDMONT_PLUS 0x7A /* Gemini Lake */ +#define INTEL_ATOM_GOLDMONT_PLUS IFM(6, 0x7A) /* Gemini Lake */ #define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */ +#define INTEL_ATOM_TREMONT_D IFM(6, 0x86) /* Jacobsville */ #define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */ +#define INTEL_ATOM_TREMONT IFM(6, 0x96) /* Elkhart Lake */ #define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */ +#define INTEL_ATOM_TREMONT_L IFM(6, 0x9C) /* Jasper Lake */ #define INTEL_FAM6_ATOM_GRACEMONT 0xBE /* Alderlake N */ +#define INTEL_ATOM_GRACEMONT IFM(6, 0xBE) /* Alderlake N */ #define INTEL_FAM6_ATOM_CRESTMONT_X 0xAF /* Sierra Forest */ +#define INTEL_ATOM_CRESTMONT_X IFM(6, 0xAF) /* Sierra Forest */ #define INTEL_FAM6_ATOM_CRESTMONT 0xB6 /* Grand Ridge */ +#define INTEL_ATOM_CRESTMONT IFM(6, 0xB6) /* Grand Ridge */ #define INTEL_FAM6_ATOM_DARKMONT_X 0xDD /* Clearwater Forest */ +#define INTEL_ATOM_DARKMONT_X IFM(6, 0xDD) /* Clearwater Forest */ /* Xeon Phi */ #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ +#define INTEL_XEON_PHI_KNL IFM(6, 0x57) /* Knights Landing */ #define INTEL_FAM6_XEON_PHI_KNM 0x85 /* Knights Mill */ +#define INTEL_XEON_PHI_KNM IFM(6, 0x85) /* Knights Mill */ /* Family 5 */ #define INTEL_FAM5_QUARK_X1000 0x09 /* Quark X1000 SoC */ +#define INTEL_QUARK_X1000 IFM(5, 0x09) /* Quark X1000 SoC */ #endif /* _ASM_X86_INTEL_FAMILY_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/io.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/io.h @@ -379,7 +379,7 @@ const u8 *end = from + count * 64; while (from < end) { - movdir64b(dst, from); + movdir64b_io(dst, from); from += 64; } } --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/irq_stack.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/irq_stack.h @@ -100,7 +100,7 @@ } #define ASM_CALL_ARG0 \ - "call %P[__func] \n" \ + "call %c[__func] \n" \ ASM_REACHABLE #define ASM_CALL_ARG1 \ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/kvm_host.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/kvm_host.h @@ -854,6 +854,7 @@ int cpuid_nent; struct kvm_cpuid_entry2 *cpuid_entries; struct kvm_hypervisor_cpuid kvm_cpuid; + bool is_amd_compatible; /* * FIXME: Drop this macro and use KVM_NR_GOVERNED_FEATURES directly --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/mem_encrypt.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/mem_encrypt.h @@ -15,7 +15,8 @@ #include #include -#include +#include +struct boot_params; #ifdef CONFIG_X86_MEM_ENCRYPT void __init mem_encrypt_init(void); @@ -46,8 +47,8 @@ void __init sme_early_init(void); -void __init sme_encrypt_kernel(struct boot_params *bp); -void __init sme_enable(struct boot_params *bp); +void sme_encrypt_kernel(struct boot_params *bp); +void sme_enable(struct boot_params *bp); int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size); int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size); @@ -58,6 +59,11 @@ void __init sev_es_init_vc_handling(void); +static inline u64 sme_get_me_mask(void) +{ + return RIP_REL_REF(sme_me_mask); +} + #define __bss_decrypted __section(".bss..decrypted") #else /* !CONFIG_AMD_MEM_ENCRYPT */ @@ -75,8 +81,8 @@ static inline void __init sme_early_init(void) { } -static inline void __init sme_encrypt_kernel(struct boot_params *bp) { } -static inline void __init sme_enable(struct boot_params *bp) { } +static inline void sme_encrypt_kernel(struct boot_params *bp) { } +static inline void sme_enable(struct boot_params *bp) { } static inline void sev_es_init_vc_handling(void) { } @@ -89,6 +95,8 @@ static inline void mem_encrypt_free_decrypted_mem(void) { } +static inline u64 sme_get_me_mask(void) { return 0; } + #define __bss_decrypted #endif /* CONFIG_AMD_MEM_ENCRYPT */ @@ -106,11 +114,6 @@ extern char __start_bss_decrypted[], __end_bss_decrypted[], __start_bss_decrypted_unused[]; -static inline u64 sme_get_me_mask(void) -{ - return sme_me_mask; -} - #endif /* __ASSEMBLY__ */ #endif /* __X86_MEM_ENCRYPT_H__ */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/msr-index.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/msr-index.h @@ -50,10 +50,13 @@ #define SPEC_CTRL_SSBD BIT(SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */ #define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6 /* Disable RRSBA behavior */ #define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT) +#define SPEC_CTRL_BHI_DIS_S_SHIFT 10 /* Disable Branch History Injection behavior */ +#define SPEC_CTRL_BHI_DIS_S BIT(SPEC_CTRL_BHI_DIS_S_SHIFT) /* A mask for bits which the kernel toggles when controlling mitigations */ #define SPEC_CTRL_MITIGATIONS_MASK (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \ - | SPEC_CTRL_RRSBA_DIS_S) + | SPEC_CTRL_RRSBA_DIS_S \ + | SPEC_CTRL_BHI_DIS_S) #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ @@ -152,6 +155,10 @@ * are restricted to targets in * kernel. */ +#define ARCH_CAP_BHI_NO BIT(20) /* + * CPU is not affected by Branch + * History Injection. + */ #define ARCH_CAP_PBRSB_NO BIT(24) /* * Not susceptible to Post-Barrier * Return Stack Buffer Predictions. @@ -165,6 +172,14 @@ * CPU is not vulnerable to Gather * Data Sampling (GDS). */ +#define ARCH_CAP_RFDS_NO BIT(27) /* + * Not susceptible to Register + * File Data Sampling. + */ +#define ARCH_CAP_RFDS_CLEAR BIT(28) /* + * VERW clears CPU Register + * File. + */ #define ARCH_CAP_XAPIC_DISABLE BIT(21) /* * IA32_XAPIC_DISABLE_STATUS MSR --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/nospec-branch.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/nospec-branch.h @@ -271,11 +271,20 @@ .Lskip_rsb_\@: .endm +/* + * The CALL to srso_alias_untrain_ret() must be patched in directly at + * the spot where untraining must be done, ie., srso_alias_untrain_ret() + * must be the target of a CALL instruction instead of indirectly + * jumping to a wrapper which then calls it. Therefore, this macro is + * called outside of __UNTRAIN_RET below, for the time being, before the + * kernel can support nested alternatives with arbitrary nesting. + */ +.macro CALL_UNTRAIN_RET #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO) -#define CALL_UNTRAIN_RET "call entry_untrain_ret" -#else -#define CALL_UNTRAIN_RET "" + ALTERNATIVE_2 "", "call entry_untrain_ret", X86_FEATURE_UNRET, \ + "call srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS #endif +.endm /* * Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the @@ -291,8 +300,8 @@ .macro __UNTRAIN_RET ibpb_feature, call_depth_insns #if defined(CONFIG_RETHUNK) || defined(CONFIG_CPU_IBPB_ENTRY) VALIDATE_UNRET_END - ALTERNATIVE_3 "", \ - CALL_UNTRAIN_RET, X86_FEATURE_UNRET, \ + CALL_UNTRAIN_RET + ALTERNATIVE_2 "", \ "call entry_ibpb", \ibpb_feature, \ __stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH #endif @@ -326,6 +335,19 @@ ALTERNATIVE "", __stringify(verw _ASM_RIP(mds_verw_sel)), X86_FEATURE_CLEAR_CPU_BUF .endm +#ifdef CONFIG_X86_64 +.macro CLEAR_BRANCH_HISTORY + ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP +.endm + +.macro CLEAR_BRANCH_HISTORY_VMEXIT + ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT +.endm +#else +#define CLEAR_BRANCH_HISTORY +#define CLEAR_BRANCH_HISTORY_VMEXIT +#endif + #else /* __ASSEMBLY__ */ #define ANNOTATE_RETPOLINE_SAFE \ @@ -351,6 +373,8 @@ static inline void retbleed_return_thunk(void) {} #endif +extern void srso_alias_untrain_ret(void); + #ifdef CONFIG_CPU_SRSO extern void srso_return_thunk(void); extern void srso_alias_return_thunk(void); @@ -366,6 +390,10 @@ extern void entry_untrain_ret(void); extern void entry_ibpb(void); +#ifdef CONFIG_X86_64 +extern void clear_bhb_loop(void); +#endif + extern void (*x86_return_thunk)(void); #ifdef CONFIG_CALL_DEPTH_TRACKING --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/page.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/page.h @@ -66,10 +66,14 @@ * virt_addr_valid(kaddr) returns true. */ #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) extern bool __virt_addr_valid(unsigned long kaddr); #define virt_addr_valid(kaddr) __virt_addr_valid((unsigned long) (kaddr)) +static __always_inline void *pfn_to_kaddr(unsigned long pfn) +{ + return __va(pfn << PAGE_SHIFT); +} + static __always_inline u64 __canonical_address(u64 vaddr, u8 vaddr_bits) { return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits); --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/pci-direct.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/pci-direct.h @@ -10,9 +10,11 @@ extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset); extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset); extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset); +extern u32 pci_early_find_cap(int bus, int slot, int func, int cap); extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val); extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val); extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val); +extern unsigned int pci_early_clear_msi; extern int early_pci_allowed(void); #endif /* _ASM_X86_PCI_DIRECT_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/pgtable_types.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/pgtable_types.h @@ -148,7 +148,7 @@ #define _COMMON_PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ _PAGE_SPECIAL | _PAGE_ACCESSED | \ _PAGE_DIRTY_BITS | _PAGE_SOFT_DIRTY | \ - _PAGE_DEVMAP | _PAGE_ENC | _PAGE_UFFD_WP) + _PAGE_DEVMAP | _PAGE_CC | _PAGE_UFFD_WP) #define _PAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PAT) #define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE) @@ -173,6 +173,7 @@ }; #endif +#define _PAGE_CC (_AT(pteval_t, cc_mask)) #define _PAGE_ENC (_AT(pteval_t, sme_me_mask)) #define _PAGE_CACHE_MASK (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT) @@ -566,6 +567,8 @@ extern pte_t *lookup_address(unsigned long address, unsigned int *level); extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, unsigned int *level); +pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address, + unsigned int *level, bool *nx, bool *rw); extern pmd_t *lookup_pmd_address(unsigned long address); extern phys_addr_t slow_virt_to_phys(void *__address); extern int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/processor.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/processor.h @@ -479,7 +479,6 @@ unsigned long iopl_emul; unsigned int iopl_warn:1; - unsigned int sig_on_uaccess_err:1; /* * Protection Keys Register for Userspace. Loaded immediately on --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/required-features.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/required-features.h @@ -99,6 +99,7 @@ #define REQUIRED_MASK18 0 #define REQUIRED_MASK19 0 #define REQUIRED_MASK20 0 -#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21) +#define REQUIRED_MASK21 0 +#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22) #endif /* _ASM_X86_REQUIRED_FEATURES_H */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/sev.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/sev.h @@ -199,16 +199,16 @@ struct snp_guest_request_ioctl; void setup_ghcb(void); -void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, - unsigned long npages); -void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, - unsigned long npages); -void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op); +void early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, + unsigned long npages); +void early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, + unsigned long npages); void snp_set_memory_shared(unsigned long vaddr, unsigned long npages); void snp_set_memory_private(unsigned long vaddr, unsigned long npages); void snp_set_wakeup_secondary_cpu(void); bool snp_init(struct boot_params *bp); -void __init __noreturn snp_abort(void); +void __noreturn snp_abort(void); +void snp_dmi_setup(void); int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio); void snp_accept_memory(phys_addr_t start, phys_addr_t end); u64 snp_get_unsupported_features(u64 status); @@ -227,12 +227,12 @@ early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { } static inline void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { } -static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { } static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { } static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { } static inline void snp_set_wakeup_secondary_cpu(void) { } static inline bool snp_init(struct boot_params *bp) { return false; } static inline void snp_abort(void) { } +static inline void snp_dmi_setup(void) { } static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio) { return -ENOTTY; --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/sparsemem.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/sparsemem.h @@ -37,8 +37,6 @@ #define phys_to_target_node phys_to_target_node extern int memory_add_physaddr_to_nid(u64 start); #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid -extern int numa_fill_memblks(u64 start, u64 end); -#define numa_fill_memblks numa_fill_memblks #endif #endif /* __ASSEMBLY__ */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/special_insns.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/special_insns.h @@ -224,10 +224,10 @@ } /* The dst parameter must be 64-bytes aligned */ -static inline void movdir64b(void __iomem *dst, const void *src) +static inline void movdir64b(void *dst, const void *src) { const struct { char _[64]; } *__src = src; - struct { char _[64]; } __iomem *__dst = dst; + struct { char _[64]; } *__dst = dst; /* * MOVDIR64B %(rdx), rax. @@ -245,6 +245,11 @@ : "m" (*__src), "a" (__dst), "d" (__src)); } +static inline void movdir64b_io(void __iomem *dst, const void *src) +{ + movdir64b((void __force *)dst, src); +} + /** * enqcmds - Enqueue a command in supervisor (CPL0) mode * @dst: destination, in MMIO space (must be 512-bit aligned) --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/suspend_32.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/suspend_32.h @@ -12,11 +12,6 @@ /* image of the saved processor state */ struct saved_context { - /* - * On x86_32, all segment registers except gs are saved at kernel - * entry in pt_regs. - */ - u16 gs; unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; struct saved_msrs saved_msrs; @@ -27,6 +22,11 @@ unsigned long tr; unsigned long safety; unsigned long return_address; + /* + * On x86_32, all segment registers except gs are saved at kernel + * entry in pt_regs. + */ + u16 gs; bool misc_enable_saved; } __attribute__((packed)); --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/syscall.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/syscall.h @@ -16,19 +16,17 @@ #include /* for TS_COMPAT */ #include +/* This is used purely for kernel/trace/trace_syscalls.c */ typedef long (*sys_call_ptr_t)(const struct pt_regs *); extern const sys_call_ptr_t sys_call_table[]; -#if defined(CONFIG_X86_32) -#define ia32_sys_call_table sys_call_table -#else /* * These may not exist, but still put the prototypes in so we * can use IS_ENABLED(). */ -extern const sys_call_ptr_t ia32_sys_call_table[]; -extern const sys_call_ptr_t x32_sys_call_table[]; -#endif +extern long ia32_sys_call(const struct pt_regs *, unsigned int nr); +extern long x32_sys_call(const struct pt_regs *, unsigned int nr); +extern long x64_sys_call(const struct pt_regs *, unsigned int nr); /* * Only the low 32 bits of orig_ax are meaningful, so we return int. @@ -127,6 +125,7 @@ } bool do_syscall_64(struct pt_regs *regs, int nr); +void do_int80_emulation(struct pt_regs *regs); #endif /* CONFIG_X86_32 */ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/uaccess.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/uaccess.h @@ -78,10 +78,10 @@ int __ret_gu; \ register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ __chk_user_ptr(ptr); \ - asm volatile("call __" #fn "_%P4" \ + asm volatile("call __" #fn "_%c[size]" \ : "=a" (__ret_gu), "=r" (__val_gu), \ ASM_CALL_CONSTRAINT \ - : "0" (ptr), "i" (sizeof(*(ptr)))); \ + : "0" (ptr), [size] "i" (sizeof(*(ptr)))); \ instrument_get_user(__val_gu); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ __builtin_expect(__ret_gu, 0); \ @@ -177,7 +177,7 @@ __chk_user_ptr(__ptr); \ __ptr_pu = __ptr; \ __val_pu = __x; \ - asm volatile("call __" #fn "_%P[size]" \ + asm volatile("call __" #fn "_%c[size]" \ : "=c" (__ret_pu), \ ASM_CALL_CONSTRAINT \ : "0" (__ptr_pu), \ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/vmware.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/vmware.h @@ -7,26 +7,322 @@ #include /* - * The hypercall definitions differ in the low word of the %edx argument - * in the following way: the old port base interface uses the port - * number to distinguish between high- and low bandwidth versions. + * VMware hypercall ABI. + * + * - Low bandwidth (LB) hypercalls (I/O port based, vmcall and vmmcall) + * have up to 6 input and 6 output arguments passed and returned using + * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3), + * %esi (arg4), %edi (arg5). + * The following input arguments must be initialized by the caller: + * arg0 - VMWARE_HYPERVISOR_MAGIC + * arg2 - Hypercall command + * arg3 bits [15:0] - Port number, LB and direction flags + * + * - Low bandwidth TDX hypercalls (x86_64 only) are similar to LB + * hypercalls. They also have up to 6 input and 6 output on registers + * arguments, with different argument to register mapping: + * %r12 (arg0), %rbx (arg1), %r13 (arg2), %rdx (arg3), + * %rsi (arg4), %rdi (arg5). + * + * - High bandwidth (HB) hypercalls are I/O port based only. They have + * up to 7 input and 7 output arguments passed and returned using + * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3), + * %esi (arg4), %edi (arg5), %ebp (arg6). + * The following input arguments must be initialized by the caller: + * arg0 - VMWARE_HYPERVISOR_MAGIC + * arg1 - Hypercall command + * arg3 bits [15:0] - Port number, HB and direction flags + * + * For compatibility purposes, x86_64 systems use only lower 32 bits + * for input and output arguments. + * + * The hypercall definitions differ in the low word of the %edx (arg3) + * in the following way: the old I/O port based interface uses the port + * number to distinguish between high- and low bandwidth versions, and + * uses IN/OUT instructions to define transfer direction. * * The new vmcall interface instead uses a set of flags to select * bandwidth mode and transfer direction. The flags should be loaded - * into %dx by any user and are automatically replaced by the port - * number if the VMWARE_HYPERVISOR_PORT method is used. - * - * In short, new driver code should strictly use the new definition of - * %dx content. + * into arg3 by any user and are automatically replaced by the port + * number if the I/O port method is used. */ -/* Old port-based version */ -#define VMWARE_HYPERVISOR_PORT 0x5658 -#define VMWARE_HYPERVISOR_PORT_HB 0x5659 - -/* Current vmcall / vmmcall version */ -#define VMWARE_HYPERVISOR_HB BIT(0) -#define VMWARE_HYPERVISOR_OUT BIT(1) +#define VMWARE_HYPERVISOR_HB BIT(0) +#define VMWARE_HYPERVISOR_OUT BIT(1) + +#define VMWARE_HYPERVISOR_PORT 0x5658 +#define VMWARE_HYPERVISOR_PORT_HB (VMWARE_HYPERVISOR_PORT | \ + VMWARE_HYPERVISOR_HB) + +#define VMWARE_HYPERVISOR_MAGIC 0x564d5868U + +#define VMWARE_CMD_GETVERSION 10 +#define VMWARE_CMD_GETHZ 45 +#define VMWARE_CMD_GETVCPU_INFO 68 +#define VMWARE_CMD_STEALCLOCK 91 +/* + * Hypercall command mask: + * bits [6:0] command, range [0, 127] + * bits [19:16] sub-command, range [0, 15] + */ +#define VMWARE_CMD_MASK 0xf007fU + +#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0) +#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1) + +extern unsigned long vmware_hypercall_slow(unsigned long cmd, + unsigned long in1, unsigned long in3, + unsigned long in4, unsigned long in5, + u32 *out1, u32 *out2, u32 *out3, + u32 *out4, u32 *out5); + +#define VMWARE_TDX_VENDOR_LEAF 0x1af7e4909ULL +#define VMWARE_TDX_HCALL_FUNC 1 + +extern unsigned long vmware_tdx_hypercall(unsigned long cmd, + unsigned long in1, unsigned long in3, + unsigned long in4, unsigned long in5, + u32 *out1, u32 *out2, u32 *out3, + u32 *out4, u32 *out5); + +/* + * The low bandwidth call. The low word of %edx is presumed to have OUT bit + * set. The high word of %edx may contain input data from the caller. + */ +#define VMWARE_HYPERCALL \ + ALTERNATIVE_2("movw %[port], %%dx\n\t" \ + "inl (%%dx), %%eax", \ + "vmcall", X86_FEATURE_VMCALL, \ + "vmmcall", X86_FEATURE_VMW_VMMCALL) + +static inline +unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1) +{ + unsigned long out0; + + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, + NULL, NULL, NULL, NULL, NULL); + + if (unlikely(!alternatives_patched) && !__is_defined(MODULE)) + return vmware_hypercall_slow(cmd, in1, 0, 0, 0, + NULL, NULL, NULL, NULL, NULL); + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (0) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1, + u32 *out1, u32 *out2) +{ + unsigned long out0; + + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, + out1, out2, NULL, NULL, NULL); + + if (unlikely(!alternatives_patched) && !__is_defined(MODULE)) + return vmware_hypercall_slow(cmd, in1, 0, 0, 0, + out1, out2, NULL, NULL, NULL); + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0), "=b" (*out1), "=c" (*out2) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (0) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1, + u32 *out1, u32 *out2, u32 *out3) +{ + unsigned long out0; + + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, 0, 0, 0, + out1, out2, out3, NULL, NULL); + + if (unlikely(!alternatives_patched) && !__is_defined(MODULE)) + return vmware_hypercall_slow(cmd, in1, 0, 0, 0, + out1, out2, out3, NULL, NULL); + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (0) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1, + unsigned long in3, unsigned long in4, + unsigned long in5, u32 *out2) +{ + unsigned long out0; + + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, + NULL, out2, NULL, NULL, NULL); + + if (unlikely(!alternatives_patched) && !__is_defined(MODULE)) + return vmware_hypercall_slow(cmd, in1, in3, in4, in5, + NULL, out2, NULL, NULL, NULL); + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0), "=c" (*out2) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (in3), + "S" (in4), + "D" (in5) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1, + unsigned long in3, u32 *out2, + u32 *out3, u32 *out4, u32 *out5) +{ + unsigned long out0; + + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, in3, 0, 0, + NULL, out2, out3, out4, out5); + + if (unlikely(!alternatives_patched) && !__is_defined(MODULE)) + return vmware_hypercall_slow(cmd, in1, in3, 0, 0, + NULL, out2, out3, out4, out5); + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4), + "=D" (*out5) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (in3) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1, + unsigned long in3, unsigned long in4, + unsigned long in5, u32 *out1, + u32 *out2, u32 *out3) +{ + unsigned long out0; + + if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return vmware_tdx_hypercall(cmd, in1, in3, in4, in5, + out1, out2, out3, NULL, NULL); + + if (unlikely(!alternatives_patched) && !__is_defined(MODULE)) + return vmware_hypercall_slow(cmd, in1, in3, in4, in5, + out1, out2, out3, NULL, NULL); + + asm_inline volatile (VMWARE_HYPERCALL + : "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (in3), + "S" (in4), + "D" (in5) + : "cc", "memory"); + return out0; +} + +#ifdef CONFIG_X86_64 +#define VMW_BP_CONSTRAINT "r" +#else +#define VMW_BP_CONSTRAINT "m" +#endif + +/* + * High bandwidth calls are not supported on encrypted memory guests. + * The caller should check cc_platform_has(CC_ATTR_MEM_ENCRYPT) and use + * low bandwidth hypercall if memory encryption is set. + * This assumption simplifies HB hypercall implementation to just I/O port + * based approach without alternative patching. + */ +static inline +unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2, + unsigned long in3, unsigned long in4, + unsigned long in5, unsigned long in6, + u32 *out1) +{ + unsigned long out0; + + asm_inline volatile ( + UNWIND_HINT_SAVE + "push %%" _ASM_BP "\n\t" + UNWIND_HINT_UNDEFINED + "mov %[in6], %%" _ASM_BP "\n\t" + "rep outsb\n\t" + "pop %%" _ASM_BP "\n\t" + UNWIND_HINT_RESTORE + : "=a" (out0), "=b" (*out1) + : "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (cmd), + "c" (in2), + "d" (in3 | VMWARE_HYPERVISOR_PORT_HB), + "S" (in4), + "D" (in5), + [in6] VMW_BP_CONSTRAINT (in6) + : "cc", "memory"); + return out0; +} + +static inline +unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2, + unsigned long in3, unsigned long in4, + unsigned long in5, unsigned long in6, + u32 *out1) +{ + unsigned long out0; + + asm_inline volatile ( + UNWIND_HINT_SAVE + "push %%" _ASM_BP "\n\t" + UNWIND_HINT_UNDEFINED + "mov %[in6], %%" _ASM_BP "\n\t" + "rep insb\n\t" + "pop %%" _ASM_BP "\n\t" + UNWIND_HINT_RESTORE + : "=a" (out0), "=b" (*out1) + : "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (cmd), + "c" (in2), + "d" (in3 | VMWARE_HYPERVISOR_PORT_HB), + "S" (in4), + "D" (in5), + [in6] VMW_BP_CONSTRAINT (in6) + : "cc", "memory"); + return out0; +} +#undef VMW_BP_CONSTRAINT +#undef VMWARE_HYPERCALL /* The low bandwidth call. The low word of edx is presumed clear. */ #define VMWARE_HYPERCALL \ --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/x86_init.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/x86_init.h @@ -30,12 +30,13 @@ * @reserve_resources: reserve the standard resources for the * platform * @memory_setup: platform specific memory setup - * + * @dmi_setup: platform specific DMI setup */ struct x86_init_resources { void (*probe_roms)(void); void (*reserve_resources)(void); char *(*memory_setup)(void); + void (*dmi_setup)(void); }; /** --- linux-xilinx-6.8.0.orig/arch/x86/include/asm/xen/hypervisor.h +++ linux-xilinx-6.8.0/arch/x86/include/asm/xen/hypervisor.h @@ -62,6 +62,11 @@ #ifdef CONFIG_PVH void __init xen_pvh_init(struct boot_params *boot_params); void __init mem_map_via_hcall(struct boot_params *boot_params_p); +#ifdef CONFIG_XEN_PVH +void __init xen_reserve_extra_memory(struct boot_params *bootp); +#else +static inline void xen_reserve_extra_memory(struct boot_params *bootp) { } +#endif #endif /* Lazy mode for batching updates / context switch */ --- linux-xilinx-6.8.0.orig/arch/x86/include/uapi/asm/bootparam.h +++ linux-xilinx-6.8.0/arch/x86/include/uapi/asm/bootparam.h @@ -38,6 +38,7 @@ #define XLF_EFI_KEXEC (1<<4) #define XLF_5LEVEL (1<<5) #define XLF_5LEVEL_ENABLED (1<<6) +#define XLF_MEM_ENCRYPTION (1<<7) #ifndef __ASSEMBLY__ --- linux-xilinx-6.8.0.orig/arch/x86/kernel/acpi/cppc.c +++ linux-xilinx-6.8.0/arch/x86/kernel/acpi/cppc.c @@ -20,7 +20,7 @@ (boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f))) return true; else if (boot_cpu_data.x86 == 0x17 && - boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f) + boot_cpu_data.x86_model >= 0x30 && boot_cpu_data.x86_model <= 0x7f) return true; return boot_cpu_has(X86_FEATURE_CPPC); } --- linux-xilinx-6.8.0.orig/arch/x86/kernel/amd_nb.c +++ linux-xilinx-6.8.0/arch/x86/kernel/amd_nb.c @@ -214,7 +214,14 @@ int amd_smn_read(u16 node, u32 address, u32 *value) { - return __amd_smn_rw(node, address, value, false); + int err = __amd_smn_rw(node, address, value, false); + + if (PCI_POSSIBLE_ERROR(*value)) { + err = -ENODEV; + *value = 0; + } + + return err; } EXPORT_SYMBOL_GPL(amd_smn_read); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/aperture_64.c +++ linux-xilinx-6.8.0/arch/x86/kernel/aperture_64.c @@ -136,32 +136,6 @@ } -/* Find a PCI capability */ -static u32 __init find_cap(int bus, int slot, int func, int cap) -{ - int bytes; - u8 pos; - - if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) & - PCI_STATUS_CAP_LIST)) - return 0; - - pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST); - for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { - u8 id; - - pos &= ~3; - id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID); - if (id == 0xff) - break; - if (id == cap) - return pos; - pos = read_pci_config_byte(bus, slot, func, - pos+PCI_CAP_LIST_NEXT); - } - return 0; -} - /* Read a standard AGPv3 bridge header */ static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order) { @@ -250,8 +224,8 @@ case PCI_CLASS_BRIDGE_HOST: case PCI_CLASS_BRIDGE_OTHER: /* needed? */ /* AGP bridge? */ - cap = find_cap(bus, slot, func, - PCI_CAP_ID_AGP); + cap = pci_early_find_cap(bus, slot, + func, PCI_CAP_ID_AGP); if (!cap) break; *valid_agp = 1; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/apic/apic.c +++ linux-xilinx-6.8.0/arch/x86/kernel/apic/apic.c @@ -1724,11 +1724,11 @@ static bool x2apic_hw_locked(void) { - u64 ia32_cap; + u64 x86_arch_cap_msr; u64 msr; - ia32_cap = x86_read_arch_cap_msr(); - if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) { + x86_arch_cap_msr = x86_read_arch_cap_msr(); + if (x86_arch_cap_msr & ARCH_CAP_XAPIC_DISABLE) { rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr); return (msr & LEGACY_XAPIC_DISABLED); } @@ -1808,7 +1808,7 @@ __x2apic_enable(); } -static __init void apic_set_fixmap(void); +static __init void apic_set_fixmap(bool read_apic); static __init void x2apic_disable(void) { @@ -1830,7 +1830,12 @@ } __x2apic_disable(); - apic_set_fixmap(); + /* + * Don't reread the APIC ID as it was already done from + * check_x2apic() and the APIC driver still is a x2APIC variant, + * which fails to do the read after x2APIC was disabled. + */ + apic_set_fixmap(false); } static __init void x2apic_enable(void) @@ -2095,13 +2100,14 @@ } } -static __init void apic_set_fixmap(void) +static __init void apic_set_fixmap(bool read_apic) { set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); apic_mmio_base = APIC_BASE; apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", apic_mmio_base, mp_lapic_addr); - apic_read_boot_cpu_id(false); + if (read_apic) + apic_read_boot_cpu_id(false); } void __init register_lapic_address(unsigned long address) @@ -2111,7 +2117,7 @@ mp_lapic_addr = address; if (!x2apic_mode) - apic_set_fixmap(); + apic_set_fixmap(true); } /* --- linux-xilinx-6.8.0.orig/arch/x86/kernel/apic/vector.c +++ linux-xilinx-6.8.0/arch/x86/kernel/apic/vector.c @@ -1036,7 +1036,8 @@ add_timer_on(&cl->timer, cpu); } } else { - apicd->prev_vector = 0; + pr_warn("IRQ %u schedule cleanup for offline CPU %u\n", apicd->irq, cpu); + free_moved_vector(apicd); } raw_spin_unlock(&vector_lock); } @@ -1073,6 +1074,7 @@ */ void irq_force_complete_move(struct irq_desc *desc) { + unsigned int cpu = smp_processor_id(); struct apic_chip_data *apicd; struct irq_data *irqd; unsigned int vector; @@ -1097,10 +1099,11 @@ goto unlock; /* - * If prev_vector is empty, no action required. + * If prev_vector is empty or the descriptor is neither currently + * nor previously on the outgoing CPU no action required. */ vector = apicd->prev_vector; - if (!vector) + if (!vector || (apicd->cpu != cpu && apicd->prev_cpu != cpu)) goto unlock; /* --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/amd.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/amd.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -572,8 +573,7 @@ case 0x1a: switch (c->x86_model) { - case 0x00 ... 0x0f: - case 0x20 ... 0x2f: + case 0x00 ... 0x2f: case 0x40 ... 0x4f: case 0x70 ... 0x7f: setup_force_cpu_cap(X86_FEATURE_ZEN5); @@ -926,6 +926,11 @@ clear_rdrand_cpuid_bit(c); } +static const struct x86_cpu_desc erratum_1386_microcode[] = { + AMD_CPU_DESC(0x17, 0x1, 0x2, 0x0800126e), + AMD_CPU_DESC(0x17, 0x31, 0x0, 0x08301052), +}; + static void fix_erratum_1386(struct cpuinfo_x86 *c) { /* @@ -935,7 +940,13 @@ * * Affected parts all have no supervisor XSAVE states, meaning that * the XSAVEC instruction (which works fine) is equivalent. + * + * Clear the feature flag only on microcode revisions which + * don't have the fix. */ + if (x86_cpu_has_min_microcode_rev(erratum_1386_microcode)) + return; + clear_cpu_cap(c, X86_FEATURE_XSAVES); } @@ -989,11 +1000,11 @@ u32 good_rev = 0; switch (boot_cpu_data.x86_model) { - case 0x30 ... 0x3f: good_rev = 0x0830107a; break; - case 0x60 ... 0x67: good_rev = 0x0860010b; break; - case 0x68 ... 0x6f: good_rev = 0x08608105; break; - case 0x70 ... 0x7f: good_rev = 0x08701032; break; - case 0xa0 ... 0xaf: good_rev = 0x08a00008; break; + case 0x30 ... 0x3f: good_rev = 0x0830107b; break; + case 0x60 ... 0x67: good_rev = 0x0860010c; break; + case 0x68 ... 0x6f: good_rev = 0x08608107; break; + case 0x70 ... 0x7f: good_rev = 0x08701033; break; + case 0xa0 ... 0xaf: good_rev = 0x08a00009; break; default: return false; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/bugs.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/bugs.c @@ -61,6 +61,8 @@ u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; EXPORT_SYMBOL_GPL(x86_pred_cmd); +static u64 __ro_after_init x86_arch_cap_msr; + static DEFINE_MUTEX(spec_ctrl_mutex); void (*x86_return_thunk)(void) __ro_after_init = __x86_return_thunk; @@ -144,6 +146,8 @@ x86_spec_ctrl_base &= ~SPEC_CTRL_MITIGATIONS_MASK; } + x86_arch_cap_msr = x86_read_arch_cap_msr(); + /* Select the proper CPU mitigations before patching alternatives: */ spectre_v1_select_mitigation(); spectre_v2_select_mitigation(); @@ -301,8 +305,6 @@ static void __init taa_select_mitigation(void) { - u64 ia32_cap; - if (!boot_cpu_has_bug(X86_BUG_TAA)) { taa_mitigation = TAA_MITIGATION_OFF; return; @@ -341,9 +343,8 @@ * On MDS_NO=1 CPUs if ARCH_CAP_TSX_CTRL_MSR is not set, microcode * update is required. */ - ia32_cap = x86_read_arch_cap_msr(); - if ( (ia32_cap & ARCH_CAP_MDS_NO) && - !(ia32_cap & ARCH_CAP_TSX_CTRL_MSR)) + if ( (x86_arch_cap_msr & ARCH_CAP_MDS_NO) && + !(x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR)) taa_mitigation = TAA_MITIGATION_UCODE_NEEDED; /* @@ -401,8 +402,6 @@ static void __init mmio_select_mitigation(void) { - u64 ia32_cap; - if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) || boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) || cpu_mitigations_off()) { @@ -413,8 +412,6 @@ if (mmio_mitigation == MMIO_MITIGATION_OFF) return; - ia32_cap = x86_read_arch_cap_msr(); - /* * Enable CPU buffer clear mitigation for host and VMM, if also affected * by MDS or TAA. Otherwise, enable mitigation for VMM only. @@ -422,6 +419,13 @@ if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) && boot_cpu_has(X86_FEATURE_RTM))) setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + + /* + * X86_FEATURE_CLEAR_CPU_BUF could be enabled by other VERW based + * mitigations, disable KVM-only mitigation in that case. + */ + if (boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF)) + static_branch_disable(&mmio_stale_data_clear); else static_branch_enable(&mmio_stale_data_clear); @@ -430,7 +434,7 @@ * be propagated to uncore buffers, clearing the Fill buffers on idle * is required irrespective of SMT state. */ - if (!(ia32_cap & ARCH_CAP_FBSDP_NO)) + if (!(x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) static_branch_enable(&mds_idle_clear); /* @@ -440,10 +444,10 @@ * FB_CLEAR or by the presence of both MD_CLEAR and L1D_FLUSH on MDS * affected systems. */ - if ((ia32_cap & ARCH_CAP_FB_CLEAR) || + if ((x86_arch_cap_msr & ARCH_CAP_FB_CLEAR) || (boot_cpu_has(X86_FEATURE_MD_CLEAR) && boot_cpu_has(X86_FEATURE_FLUSH_L1D) && - !(ia32_cap & ARCH_CAP_MDS_NO))) + !(x86_arch_cap_msr & ARCH_CAP_MDS_NO))) mmio_mitigation = MMIO_MITIGATION_VERW; else mmio_mitigation = MMIO_MITIGATION_UCODE_NEEDED; @@ -474,6 +478,57 @@ early_param("mmio_stale_data", mmio_stale_data_parse_cmdline); #undef pr_fmt +#define pr_fmt(fmt) "Register File Data Sampling: " fmt + +enum rfds_mitigations { + RFDS_MITIGATION_OFF, + RFDS_MITIGATION_VERW, + RFDS_MITIGATION_UCODE_NEEDED, +}; + +/* Default mitigation for Register File Data Sampling */ +static enum rfds_mitigations rfds_mitigation __ro_after_init = + IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_VERW : RFDS_MITIGATION_OFF; + +static const char * const rfds_strings[] = { + [RFDS_MITIGATION_OFF] = "Vulnerable", + [RFDS_MITIGATION_VERW] = "Mitigation: Clear Register File", + [RFDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", +}; + +static void __init rfds_select_mitigation(void) +{ + if (!boot_cpu_has_bug(X86_BUG_RFDS) || cpu_mitigations_off()) { + rfds_mitigation = RFDS_MITIGATION_OFF; + return; + } + if (rfds_mitigation == RFDS_MITIGATION_OFF) + return; + + if (x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR) + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF); + else + rfds_mitigation = RFDS_MITIGATION_UCODE_NEEDED; +} + +static __init int rfds_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!boot_cpu_has_bug(X86_BUG_RFDS)) + return 0; + + if (!strcmp(str, "off")) + rfds_mitigation = RFDS_MITIGATION_OFF; + else if (!strcmp(str, "on")) + rfds_mitigation = RFDS_MITIGATION_VERW; + + return 0; +} +early_param("reg_file_data_sampling", rfds_parse_cmdline); + +#undef pr_fmt #define pr_fmt(fmt) "" fmt static void __init md_clear_update_mitigation(void) @@ -498,11 +553,19 @@ taa_mitigation = TAA_MITIGATION_VERW; taa_select_mitigation(); } - if (mmio_mitigation == MMIO_MITIGATION_OFF && - boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { + /* + * MMIO_MITIGATION_OFF is not checked here so that mmio_stale_data_clear + * gets updated correctly as per X86_FEATURE_CLEAR_CPU_BUF state. + */ + if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { mmio_mitigation = MMIO_MITIGATION_VERW; mmio_select_mitigation(); } + if (rfds_mitigation == RFDS_MITIGATION_OFF && + boot_cpu_has_bug(X86_BUG_RFDS)) { + rfds_mitigation = RFDS_MITIGATION_VERW; + rfds_select_mitigation(); + } out: if (boot_cpu_has_bug(X86_BUG_MDS)) pr_info("MDS: %s\n", mds_strings[mds_mitigation]); @@ -512,6 +575,8 @@ pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]); else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) pr_info("MMIO Stale Data: Unknown: No mitigations\n"); + if (boot_cpu_has_bug(X86_BUG_RFDS)) + pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]); } static void __init md_clear_select_mitigation(void) @@ -519,11 +584,12 @@ mds_select_mitigation(); taa_select_mitigation(); mmio_select_mitigation(); + rfds_select_mitigation(); /* - * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update - * and print their mitigation after MDS, TAA and MMIO Stale Data - * mitigation selection is done. + * As these mitigations are inter-related and rely on VERW instruction + * to clear the microarchitural buffers, update and print their status + * after mitigation selection is done for each of these vulnerabilities. */ md_clear_update_mitigation(); } @@ -590,8 +656,6 @@ static void __init srbds_select_mitigation(void) { - u64 ia32_cap; - if (!boot_cpu_has_bug(X86_BUG_SRBDS)) return; @@ -600,8 +664,7 @@ * are only exposed to SRBDS when TSX is enabled or when CPU is affected * by Processor MMIO Stale Data vulnerability. */ - ia32_cap = x86_read_arch_cap_msr(); - if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) && + if ((x86_arch_cap_msr & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) srbds_mitigation = SRBDS_MITIGATION_TSX_OFF; else if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) @@ -744,7 +807,7 @@ /* Will verify below that mitigation _can_ be disabled */ /* No microcode */ - if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) { + if (!(x86_arch_cap_msr & ARCH_CAP_GDS_CTRL)) { if (gds_mitigation == GDS_MITIGATION_FORCE) { /* * This only needs to be done on the boot CPU so do it @@ -1474,20 +1537,25 @@ return SPECTRE_V2_RETPOLINE; } +static bool __ro_after_init rrsba_disabled; + /* Disable in-kernel use of non-RSB RET predictors */ static void __init spec_ctrl_disable_kernel_rrsba(void) { - u64 ia32_cap; + if (rrsba_disabled) + return; - if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL)) + if (!(x86_arch_cap_msr & ARCH_CAP_RRSBA)) { + rrsba_disabled = true; return; + } - ia32_cap = x86_read_arch_cap_msr(); + if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL)) + return; - if (ia32_cap & ARCH_CAP_RRSBA) { - x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S; - update_spec_ctrl(x86_spec_ctrl_base); - } + x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S; + update_spec_ctrl(x86_spec_ctrl_base); + rrsba_disabled = true; } static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode) @@ -1537,6 +1605,74 @@ dump_stack(); } +/* + * Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by + * branch history in userspace. Not needed if BHI_NO is set. + */ +static bool __init spec_ctrl_bhi_dis(void) +{ + if (!boot_cpu_has(X86_FEATURE_BHI_CTRL)) + return false; + + x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S; + update_spec_ctrl(x86_spec_ctrl_base); + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW); + + return true; +} + +enum bhi_mitigations { + BHI_MITIGATION_OFF, + BHI_MITIGATION_ON, +}; + +static enum bhi_mitigations bhi_mitigation __ro_after_init = + IS_ENABLED(CONFIG_MITIGATION_SPECTRE_BHI) ? BHI_MITIGATION_ON : BHI_MITIGATION_OFF; + +static int __init spectre_bhi_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!strcmp(str, "off")) + bhi_mitigation = BHI_MITIGATION_OFF; + else if (!strcmp(str, "on")) + bhi_mitigation = BHI_MITIGATION_ON; + else + pr_err("Ignoring unknown spectre_bhi option (%s)", str); + + return 0; +} +early_param("spectre_bhi", spectre_bhi_parse_cmdline); + +static void __init bhi_select_mitigation(void) +{ + if (bhi_mitigation == BHI_MITIGATION_OFF) + return; + + /* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */ + if (boot_cpu_has(X86_FEATURE_RETPOLINE) && + !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) { + spec_ctrl_disable_kernel_rrsba(); + if (rrsba_disabled) + return; + } + + if (spec_ctrl_bhi_dis()) + return; + + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + /* Mitigate KVM by default */ + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT); + pr_info("Spectre BHI mitigation: SW BHB clearing on vm exit\n"); + + /* Mitigate syscalls when the mitigation is forced =on */ + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP); + pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n"); +} + static void __init spectre_v2_select_mitigation(void) { enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); @@ -1648,6 +1784,9 @@ mode == SPECTRE_V2_RETPOLINE) spec_ctrl_disable_kernel_rrsba(); + if (boot_cpu_has(X86_BUG_BHI)) + bhi_select_mitigation(); + spectre_v2_enabled = mode; pr_info("%s\n", spectre_v2_strings[mode]); @@ -1762,8 +1901,6 @@ /* Update the static key controlling the MDS CPU buffer clear in idle */ static void update_mds_branch_idle(void) { - u64 ia32_cap = x86_read_arch_cap_msr(); - /* * Enable the idle clearing if SMT is active on CPUs which are * affected only by MSBDS and not any other MDS variant. @@ -1778,7 +1915,7 @@ if (sched_smt_active()) { static_branch_enable(&mds_idle_clear); } else if (mmio_mitigation == MMIO_MITIGATION_OFF || - (ia32_cap & ARCH_CAP_FBSDP_NO)) { + (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) { static_branch_disable(&mds_idle_clear); } } @@ -2612,6 +2749,11 @@ sched_smt_active() ? "vulnerable" : "disabled"); } +static ssize_t rfds_show_state(char *buf) +{ + return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]); +} + static char *stibp_state(void) { if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && @@ -2620,15 +2762,15 @@ switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: - return ", STIBP: disabled"; + return "; STIBP: disabled"; case SPECTRE_V2_USER_STRICT: - return ", STIBP: forced"; + return "; STIBP: forced"; case SPECTRE_V2_USER_STRICT_PREFERRED: - return ", STIBP: always-on"; + return "; STIBP: always-on"; case SPECTRE_V2_USER_PRCTL: case SPECTRE_V2_USER_SECCOMP: if (static_key_enabled(&switch_to_cond_stibp)) - return ", STIBP: conditional"; + return "; STIBP: conditional"; } return ""; } @@ -2637,10 +2779,10 @@ { if (boot_cpu_has(X86_FEATURE_IBPB)) { if (static_key_enabled(&switch_mm_always_ibpb)) - return ", IBPB: always-on"; + return "; IBPB: always-on"; if (static_key_enabled(&switch_mm_cond_ibpb)) - return ", IBPB: conditional"; - return ", IBPB: disabled"; + return "; IBPB: conditional"; + return "; IBPB: disabled"; } return ""; } @@ -2650,14 +2792,32 @@ if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) || boot_cpu_has(X86_FEATURE_RSB_VMEXIT)) - return ", PBRSB-eIBRS: SW sequence"; + return "; PBRSB-eIBRS: SW sequence"; else - return ", PBRSB-eIBRS: Vulnerable"; + return "; PBRSB-eIBRS: Vulnerable"; } else { - return ", PBRSB-eIBRS: Not affected"; + return "; PBRSB-eIBRS: Not affected"; } } +static const char *spectre_bhi_state(void) +{ + if (!boot_cpu_has_bug(X86_BUG_BHI)) + return "; BHI: Not affected"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW)) + return "; BHI: BHI_DIS_S"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP)) + return "; BHI: SW loop, KVM: SW loop"; + else if (boot_cpu_has(X86_FEATURE_RETPOLINE) && + !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE) && + rrsba_disabled) + return "; BHI: Retpoline"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT)) + return "; BHI: Vulnerable, KVM: SW loop"; + + return "; BHI: Vulnerable"; +} + static ssize_t spectre_v2_show_state(char *buf) { if (spectre_v2_enabled == SPECTRE_V2_LFENCE) @@ -2670,13 +2830,15 @@ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); - return sysfs_emit(buf, "%s%s%s%s%s%s%s\n", + return sysfs_emit(buf, "%s%s%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], ibpb_state(), - boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "", stibp_state(), - boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", + boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "", pbrsb_eibrs_state(), + spectre_bhi_state(), + /* this should always be at the end */ spectre_v2_module_string()); } @@ -2771,6 +2933,9 @@ case X86_BUG_GDS: return gds_show_state(buf); + case X86_BUG_RFDS: + return rfds_show_state(buf); + default: break; } @@ -2845,4 +3010,9 @@ { return cpu_show_common(dev, attr, buf, X86_BUG_GDS); } + +ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_RFDS); +} #endif --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/cacheinfo.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/cacheinfo.c @@ -178,7 +178,16 @@ struct amd_northbridge *nb; }; -static unsigned short num_cache_leaves; +static inline unsigned int get_num_cache_leaves(unsigned int cpu) +{ + return get_cpu_cacheinfo(cpu)->num_leaves; +} + +static inline void +set_num_cache_leaves(unsigned int nr_leaves, unsigned int cpu) +{ + get_cpu_cacheinfo(cpu)->num_leaves = nr_leaves; +} /* AMD doesn't have CPUID4. Emulate it here to report the same information to the user. This makes some assumptions about the machine: @@ -718,19 +727,21 @@ void init_amd_cacheinfo(struct cpuinfo_x86 *c) { + unsigned int cpu = c->cpu_index; + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { - num_cache_leaves = find_num_cache_leaves(c); + set_num_cache_leaves(find_num_cache_leaves(c), cpu); } else if (c->extended_cpuid_level >= 0x80000006) { if (cpuid_edx(0x80000006) & 0xf000) - num_cache_leaves = 4; + set_num_cache_leaves(4, cpu); else - num_cache_leaves = 3; + set_num_cache_leaves(3, cpu); } } void init_hygon_cacheinfo(struct cpuinfo_x86 *c) { - num_cache_leaves = find_num_cache_leaves(c); + set_num_cache_leaves(find_num_cache_leaves(c), c->cpu_index); } void init_intel_cacheinfo(struct cpuinfo_x86 *c) @@ -742,19 +753,19 @@ unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; if (c->cpuid_level > 3) { - static int is_initialized; - - if (is_initialized == 0) { - /* Init num_cache_leaves from boot CPU */ - num_cache_leaves = find_num_cache_leaves(c); - is_initialized++; - } + /* + * There should be at least one leaf. A non-zero value means + * that the number of leaves has been initialized. + */ + if (!get_num_cache_leaves(c->cpu_index)) + set_num_cache_leaves(find_num_cache_leaves(c), + c->cpu_index); /* * Whenever possible use cpuid(4), deterministic cache * parameters cpuid leaf to find the cache details */ - for (i = 0; i < num_cache_leaves; i++) { + for (i = 0; i < get_num_cache_leaves(c->cpu_index); i++) { struct _cpuid4_info_regs this_leaf = {}; int retval; @@ -790,14 +801,14 @@ * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for * trace cache */ - if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + if ((!get_num_cache_leaves(c->cpu_index) || c->x86 == 15) && c->cpuid_level > 1) { /* supports eax=2 call */ int j, n; unsigned int regs[4]; unsigned char *dp = (unsigned char *)regs; int only_trace = 0; - if (num_cache_leaves != 0 && c->x86 == 15) + if (get_num_cache_leaves(c->cpu_index) && c->x86 == 15) only_trace = 1; /* Number of times to iterate */ @@ -991,14 +1002,6 @@ int init_cache_level(unsigned int cpu) { - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - - if (!num_cache_leaves) - return -ENOENT; - if (!this_cpu_ci) - return -EINVAL; - this_cpu_ci->num_levels = 3; - this_cpu_ci->num_leaves = num_cache_leaves; return 0; } --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/common.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/common.c @@ -1096,18 +1096,9 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; - bool vp_bits_from_cpuid = true; if (!cpu_has(c, X86_FEATURE_CPUID) || - (c->extended_cpuid_level < 0x80000008)) - vp_bits_from_cpuid = false; - - if (vp_bits_from_cpuid) { - cpuid(0x80000008, &eax, &ebx, &ecx, &edx); - - c->x86_virt_bits = (eax >> 8) & 0xff; - c->x86_phys_bits = eax & 0xff; - } else { + (c->extended_cpuid_level < 0x80000008)) { if (IS_ENABLED(CONFIG_X86_64)) { c->x86_clflush_size = 64; c->x86_phys_bits = 36; @@ -1121,7 +1112,17 @@ cpu_has(c, X86_FEATURE_PSE36)) c->x86_phys_bits = 36; } + } else { + cpuid(0x80000008, &eax, &ebx, &ecx, &edx); + + c->x86_virt_bits = (eax >> 8) & 0xff; + c->x86_phys_bits = eax & 0xff; + + /* Provide a sane default if not enumerated: */ + if (!c->x86_clflush_size) + c->x86_clflush_size = 32; } + c->x86_cache_bits = c->x86_phys_bits; c->x86_cache_alignment = c->x86_clflush_size; } @@ -1163,6 +1164,7 @@ #define NO_SPECTRE_V2 BIT(8) #define NO_MMIO BIT(9) #define NO_EIBRS_PBRSB BIT(10) +#define NO_BHI BIT(11) #define VULNWL(vendor, family, model, whitelist) \ X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist) @@ -1225,18 +1227,18 @@ VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), /* AMD Family 0xf - 0x12 */ - VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), - VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), - VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), - VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), + VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ - VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB), - VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB), + VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI), + VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI), /* Zhaoxin Family 7 */ - VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO), - VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO), + VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI), + VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI), {} }; @@ -1267,6 +1269,8 @@ #define SRSO BIT(5) /* CPU is affected by GDS */ #define GDS BIT(6) +/* CPU is affected by Register File Data Sampling */ +#define RFDS BIT(7) static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), @@ -1294,9 +1298,18 @@ VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS), VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS), - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS), + VULNBL_INTEL_STEPPINGS(ALDERLAKE, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ALDERLAKE_L, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(RAPTORLAKE, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(RAPTORLAKE_P, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(RAPTORLAKE_S, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_GRACEMONT, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO | RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_D, X86_STEPPING_ANY, RFDS), + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_PLUS, X86_STEPPING_ANY, RFDS), VULNBL_AMD(0x15, RETBLEED), VULNBL_AMD(0x16, RETBLEED), @@ -1315,28 +1328,46 @@ u64 x86_read_arch_cap_msr(void) { - u64 ia32_cap = 0; + u64 x86_arch_cap_msr = 0; if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) - rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, x86_arch_cap_msr); + + return x86_arch_cap_msr; +} - return ia32_cap; +static bool arch_cap_mmio_immune(u64 x86_arch_cap_msr) +{ + return (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO && + x86_arch_cap_msr & ARCH_CAP_PSDP_NO && + x86_arch_cap_msr & ARCH_CAP_SBDR_SSDP_NO); } -static bool arch_cap_mmio_immune(u64 ia32_cap) +static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr) { - return (ia32_cap & ARCH_CAP_FBSDP_NO && - ia32_cap & ARCH_CAP_PSDP_NO && - ia32_cap & ARCH_CAP_SBDR_SSDP_NO); + /* The "immunity" bit trumps everything else: */ + if (x86_arch_cap_msr & ARCH_CAP_RFDS_NO) + return false; + + /* + * VMMs set ARCH_CAP_RFDS_CLEAR for processors not in the blacklist to + * indicate that mitigation is needed because guest is running on a + * vulnerable hardware or may migrate to such hardware: + */ + if (x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR) + return true; + + /* Only consult the blacklist when there is no enumeration: */ + return cpu_matches(cpu_vuln_blacklist, RFDS); } static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) { - u64 ia32_cap = x86_read_arch_cap_msr(); + u64 x86_arch_cap_msr = x86_read_arch_cap_msr(); /* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */ if (!cpu_matches(cpu_vuln_whitelist, NO_ITLB_MULTIHIT) && - !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO)) + !(x86_arch_cap_msr & ARCH_CAP_PSCHANGE_MC_NO)) setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT); if (cpu_matches(cpu_vuln_whitelist, NO_SPECULATION)) @@ -1348,7 +1379,7 @@ setup_force_cpu_bug(X86_BUG_SPECTRE_V2); if (!cpu_matches(cpu_vuln_whitelist, NO_SSB) && - !(ia32_cap & ARCH_CAP_SSB_NO) && + !(x86_arch_cap_msr & ARCH_CAP_SSB_NO) && !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); @@ -1356,15 +1387,15 @@ * AMD's AutoIBRS is equivalent to Intel's eIBRS - use the Intel feature * flag and protect from vendor-specific bugs via the whitelist. */ - if ((ia32_cap & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) { + if ((x86_arch_cap_msr & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) { setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED); if (!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) && - !(ia32_cap & ARCH_CAP_PBRSB_NO)) + !(x86_arch_cap_msr & ARCH_CAP_PBRSB_NO)) setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB); } if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) && - !(ia32_cap & ARCH_CAP_MDS_NO)) { + !(x86_arch_cap_msr & ARCH_CAP_MDS_NO)) { setup_force_cpu_bug(X86_BUG_MDS); if (cpu_matches(cpu_vuln_whitelist, MSBDS_ONLY)) setup_force_cpu_bug(X86_BUG_MSBDS_ONLY); @@ -1383,9 +1414,9 @@ * TSX_CTRL check alone is not sufficient for cases when the microcode * update is not present or running as guest that don't get TSX_CTRL. */ - if (!(ia32_cap & ARCH_CAP_TAA_NO) && + if (!(x86_arch_cap_msr & ARCH_CAP_TAA_NO) && (cpu_has(c, X86_FEATURE_RTM) || - (ia32_cap & ARCH_CAP_TSX_CTRL_MSR))) + (x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR))) setup_force_cpu_bug(X86_BUG_TAA); /* @@ -1411,7 +1442,7 @@ * Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist, * nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits. */ - if (!arch_cap_mmio_immune(ia32_cap)) { + if (!arch_cap_mmio_immune(x86_arch_cap_msr)) { if (cpu_matches(cpu_vuln_blacklist, MMIO)) setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO)) @@ -1419,7 +1450,7 @@ } if (!cpu_has(c, X86_FEATURE_BTC_NO)) { - if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA)) + if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (x86_arch_cap_msr & ARCH_CAP_RSBA)) setup_force_cpu_bug(X86_BUG_RETBLEED); } @@ -1437,15 +1468,25 @@ * disabling AVX2. The only way to do this in HW is to clear XCR0[2], * which means that AVX will be disabled. */ - if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) && + if (cpu_matches(cpu_vuln_blacklist, GDS) && !(x86_arch_cap_msr & ARCH_CAP_GDS_NO) && boot_cpu_has(X86_FEATURE_AVX)) setup_force_cpu_bug(X86_BUG_GDS); + if (vulnerable_to_rfds(x86_arch_cap_msr)) + setup_force_cpu_bug(X86_BUG_RFDS); + + /* When virtualized, eIBRS could be hidden, assume vulnerable */ + if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) && + !cpu_matches(cpu_vuln_whitelist, NO_BHI) && + (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) || + boot_cpu_has(X86_FEATURE_HYPERVISOR))) + setup_force_cpu_bug(X86_BUG_BHI); + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; /* Rogue Data Cache Load? No! */ - if (ia32_cap & ARCH_CAP_RDCL_NO) + if (x86_arch_cap_msr & ARCH_CAP_RDCL_NO) return; setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); @@ -1587,6 +1628,7 @@ if (have_cpuid_p()) { cpu_detect(c); get_cpu_vendor(c); + intel_unlock_cpuid_leafs(c); get_cpu_cap(c); setup_force_cpu_cap(X86_FEATURE_CPUID); get_cpu_address_sizes(c); @@ -1743,7 +1785,7 @@ cpu_detect(c); get_cpu_vendor(c); - + intel_unlock_cpuid_leafs(c); get_cpu_cap(c); get_cpu_address_sizes(c); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/cpu.h +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/cpu.h @@ -56,9 +56,11 @@ extern void __init tsx_init(void); void tsx_ap_init(void); +void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c); #else static inline void tsx_init(void) { } static inline void tsx_ap_init(void) { } +static inline void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c) { } #endif /* CONFIG_CPU_SUP_INTEL */ extern void init_spectral_chicken(struct cpuinfo_x86 *c); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/cpuid-deps.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/cpuid-deps.c @@ -44,7 +44,10 @@ { X86_FEATURE_F16C, X86_FEATURE_XMM2, }, { X86_FEATURE_AES, X86_FEATURE_XMM2 }, { X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 }, + { X86_FEATURE_GFNI, X86_FEATURE_XMM2 }, { X86_FEATURE_FMA, X86_FEATURE_AVX }, + { X86_FEATURE_VAES, X86_FEATURE_AVX }, + { X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX }, { X86_FEATURE_AVX2, X86_FEATURE_AVX, }, { X86_FEATURE_AVX512F, X86_FEATURE_AVX, }, { X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F }, @@ -56,9 +59,6 @@ { X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F }, { X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F }, { X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL }, - { X86_FEATURE_GFNI, X86_FEATURE_AVX512VL }, - { X86_FEATURE_VAES, X86_FEATURE_AVX512VL }, - { X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX512VL }, { X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL }, { X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL }, { X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F }, --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/intel.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/intel.c @@ -268,19 +268,26 @@ c->x86_phys_bits -= keyid_bits; } +void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c) +{ + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return; + + if (c->x86 < 6 || (c->x86 == 6 && c->x86_model < 0xd)) + return; + + /* + * The BIOS can have limited CPUID to leaf 2, which breaks feature + * enumeration. Unlock it and update the maximum leaf info. + */ + if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0) + c->cpuid_level = cpuid_eax(0); +} + static void early_init_intel(struct cpuinfo_x86 *c) { u64 misc_enable; - /* Unmask CPUID levels if masked: */ - if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) { - if (msr_clear_bit(MSR_IA32_MISC_ENABLE, - MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0) { - c->cpuid_level = cpuid_eax(0); - get_cpu_cap(c); - } - } - if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/match.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/match.c @@ -17,8 +17,7 @@ * * A typical table entry would be to match a specific CPU * - * X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_BROADWELL, - * X86_FEATURE_ANY, NULL); + * X86_MATCH_VFM_FEATURE(INTEL_BROADWELL, X86_FEATURE_ANY, NULL); * * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY, * %X86_MODEL_ANY, %X86_FEATURE_ANY (except for vendor) @@ -39,9 +38,7 @@ const struct x86_cpu_id *m; struct cpuinfo_x86 *c = &boot_cpu_data; - for (m = match; - m->vendor | m->family | m->model | m->steppings | m->feature; - m++) { + for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) { if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) continue; if (m->family != X86_FAMILY_ANY && c->x86 != m->family) --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/mce/core.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/mce/core.c @@ -2474,12 +2474,14 @@ return -EINVAL; b = &per_cpu(mce_banks_array, s->id)[bank]; - if (!b->init) return -ENODEV; b->ctl = new; + + mutex_lock(&mce_sysfs_mutex); mce_restart(); + mutex_unlock(&mce_sysfs_mutex); return size; } --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/microcode/amd.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/microcode/amd.c @@ -465,7 +465,7 @@ return !__apply_microcode_amd(mc); } -static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family) +static bool get_builtin_microcode(struct cpio_data *cp, u8 family) { char fw_name[36] = "amd-ucode/microcode_amd.bin"; struct firmware fw; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/resctrl/core.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/resctrl/core.c @@ -231,9 +231,7 @@ static bool __rdt_get_mem_config_amd(struct rdt_resource *r) { struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); - union cpuid_0x10_3_eax eax; - union cpuid_0x10_x_edx edx; - u32 ebx, ecx, subleaf; + u32 eax, ebx, ecx, edx, subleaf; /* * Query CPUID_Fn80000020_EDX_x01 for MBA and @@ -241,9 +239,9 @@ */ subleaf = (r->rid == RDT_RESOURCE_SMBA) ? 2 : 1; - cpuid_count(0x80000020, subleaf, &eax.full, &ebx, &ecx, &edx.full); - hw_res->num_closid = edx.split.cos_max + 1; - r->default_ctrl = MAX_MBA_BW_AMD; + cpuid_count(0x80000020, subleaf, &eax, &ebx, &ecx, &edx); + hw_res->num_closid = edx + 1; + r->default_ctrl = 1 << eax; /* AMD does not use delay */ r->membw.delay_linear = false; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/resctrl/internal.h +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/resctrl/internal.h @@ -18,7 +18,6 @@ #define MBM_OVERFLOW_INTERVAL 1000 #define MAX_MBA_BW 100u #define MBA_IS_LINEAR 0x4 -#define MAX_MBA_BW_AMD 0x800 #define MBM_CNTR_WIDTH_OFFSET_AMD 20 #define RMID_VAL_ERROR BIT_ULL(63) @@ -296,14 +295,10 @@ * struct mbm_state - status for each MBM counter in each domain * @prev_bw_bytes: Previous bytes value read for bandwidth calculation * @prev_bw: The most recent bandwidth in MBps - * @delta_bw: Difference between the current and previous bandwidth - * @delta_comp: Indicates whether to compute the delta_bw */ struct mbm_state { u64 prev_bw_bytes; u32 prev_bw; - u32 delta_bw; - bool delta_comp; }; /** @@ -395,6 +390,8 @@ * @msr_update: Function pointer to update QOS MSRs * @mon_scale: cqm counter * mon_scale = occupancy in bytes * @mbm_width: Monitor width, to detect and correct for overflow. + * @mbm_cfg_mask: Bandwidth sources that can be tracked when Bandwidth + * Monitoring Event Configuration (BMEC) is supported. * @cdp_enabled: CDP state of this resource * * Members of this structure are either private to the architecture @@ -409,6 +406,7 @@ struct rdt_resource *r); unsigned int mon_scale; unsigned int mbm_width; + unsigned int mbm_cfg_mask; bool cdp_enabled; }; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/resctrl/monitor.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/resctrl/monitor.c @@ -440,9 +440,6 @@ cur_bw = bytes / SZ_1M; - if (m->delta_comp) - m->delta_bw = abs(cur_bw - m->prev_bw); - m->delta_comp = false; m->prev_bw = cur_bw; } @@ -520,11 +517,11 @@ { u32 closid, rmid, cur_msr_val, new_msr_val; struct mbm_state *pmbm_data, *cmbm_data; - u32 cur_bw, delta_bw, user_bw; struct rdt_resource *r_mba; struct rdt_domain *dom_mba; struct list_head *head; struct rdtgroup *entry; + u32 cur_bw, user_bw; if (!is_mbm_local_enabled()) return; @@ -543,7 +540,6 @@ cur_bw = pmbm_data->prev_bw; user_bw = dom_mba->mbps_val[closid]; - delta_bw = pmbm_data->delta_bw; /* MBA resource doesn't support CDP */ cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE); @@ -555,49 +551,31 @@ list_for_each_entry(entry, head, mon.crdtgrp_list) { cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid]; cur_bw += cmbm_data->prev_bw; - delta_bw += cmbm_data->delta_bw; } /* * Scale up/down the bandwidth linearly for the ctrl group. The * bandwidth step is the bandwidth granularity specified by the * hardware. - * - * The delta_bw is used when increasing the bandwidth so that we - * dont alternately increase and decrease the control values - * continuously. - * - * For ex: consider cur_bw = 90MBps, user_bw = 100MBps and if - * bandwidth step is 20MBps(> user_bw - cur_bw), we would keep - * switching between 90 and 110 continuously if we only check - * cur_bw < user_bw. + * Always increase throttling if current bandwidth is above the + * target set by user. + * But avoid thrashing up and down on every poll by checking + * whether a decrease in throttling is likely to push the group + * back over target. E.g. if currently throttling to 30% of bandwidth + * on a system with 10% granularity steps, check whether moving to + * 40% would go past the limit by multiplying current bandwidth by + * "(30 + 10) / 30". */ if (cur_msr_val > r_mba->membw.min_bw && user_bw < cur_bw) { new_msr_val = cur_msr_val - r_mba->membw.bw_gran; } else if (cur_msr_val < MAX_MBA_BW && - (user_bw > (cur_bw + delta_bw))) { + (user_bw > (cur_bw * (cur_msr_val + r_mba->membw.min_bw) / cur_msr_val))) { new_msr_val = cur_msr_val + r_mba->membw.bw_gran; } else { return; } resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val); - - /* - * Delta values are updated dynamically package wise for each - * rdtgrp every time the throttle MSR changes value. - * - * This is because (1)the increase in bandwidth is not perfectly - * linear and only "approximately" linear even when the hardware - * says it is linear.(2)Also since MBA is a core specific - * mechanism, the delta values vary based on number of cores used - * by the rdtgrp. - */ - pmbm_data->delta_comp = true; - list_for_each_entry(entry, head, mon.crdtgrp_list) { - cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid]; - cmbm_data->delta_comp = true; - } } static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid) @@ -813,6 +791,12 @@ return ret; if (rdt_cpu_has(X86_FEATURE_BMEC)) { + u32 eax, ebx, ecx, edx; + + /* Detect list of bandwidth sources that can be tracked */ + cpuid_count(0x80000020, 3, &eax, &ebx, &ecx, &edx); + hw_res->mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS; + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) { mbm_total_event.configurable = true; mbm_config_rftype_init("mbm_total_bytes_config"); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -1620,12 +1620,6 @@ struct mon_config_info mon_info = {0}; int ret = 0; - /* mon_config cannot be more than the supported set of events */ - if (val > MAX_EVT_CONFIG_BITS) { - rdt_last_cmd_puts("Invalid event configuration\n"); - return -EINVAL; - } - /* * Read the current config value first. If both are the same then * no need to write it again. @@ -1663,6 +1657,7 @@ static int mon_config_write(struct rdt_resource *r, char *tok, u32 evtid) { + struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); char *dom_str = NULL, *id_str; unsigned long dom_id, val; struct rdt_domain *d; @@ -1686,6 +1681,13 @@ return -EINVAL; } + /* Value from user cannot be more than the supported set of events */ + if ((val & hw_res->mbm_cfg_mask) != val) { + rdt_last_cmd_printf("Invalid event configuration: max valid mask is 0x%02x\n", + hw_res->mbm_cfg_mask); + return -EINVAL; + } + list_for_each_entry(d, &r->domains, list) { if (d->id == dom_id) { ret = mbm_config_write_domain(r, d, evtid, val); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/scattered.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/scattered.c @@ -28,6 +28,7 @@ { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 }, { X86_FEATURE_RRSBA_CTRL, CPUID_EDX, 2, 0x00000007, 2 }, + { X86_FEATURE_BHI_CTRL, CPUID_EDX, 4, 0x00000007, 2 }, { X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 }, { X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 }, { X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 }, --- linux-xilinx-6.8.0.orig/arch/x86/kernel/cpu/vmware.c +++ linux-xilinx-6.8.0/arch/x86/kernel/cpu/vmware.c @@ -41,17 +41,9 @@ #define CPUID_VMWARE_INFO_LEAF 0x40000000 #define CPUID_VMWARE_FEATURES_LEAF 0x40000010 -#define CPUID_VMWARE_FEATURES_ECX_VMMCALL BIT(0) -#define CPUID_VMWARE_FEATURES_ECX_VMCALL BIT(1) -#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 - -#define VMWARE_CMD_GETVERSION 10 -#define VMWARE_CMD_GETHZ 45 -#define VMWARE_CMD_GETVCPU_INFO 68 #define VMWARE_CMD_LEGACY_X2APIC 3 #define VMWARE_CMD_VCPU_RESERVED 31 -#define VMWARE_CMD_STEALCLOCK 91 #define STEALCLOCK_NOT_AVAILABLE (-1) #define STEALCLOCK_DISABLED 0 @@ -110,6 +102,68 @@ static unsigned long vmware_tsc_khz __ro_after_init; static u8 vmware_hypercall_mode __ro_after_init; +unsigned long vmware_hypercall_slow(unsigned long cmd, + unsigned long in1, unsigned long in3, + unsigned long in4, unsigned long in5, + u32 *out1, u32 *out2, u32 *out3, + u32 *out4, u32 *out5) +{ + unsigned long out0, rbx, rcx, rdx, rsi, rdi; + + switch (vmware_hypercall_mode) { + case CPUID_VMWARE_FEATURES_ECX_VMCALL: + asm_inline volatile ("vmcall" + : "=a" (out0), "=b" (rbx), "=c" (rcx), + "=d" (rdx), "=S" (rsi), "=D" (rdi) + : "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (in3), + "S" (in4), + "D" (in5) + : "cc", "memory"); + break; + case CPUID_VMWARE_FEATURES_ECX_VMMCALL: + asm_inline volatile ("vmmcall" + : "=a" (out0), "=b" (rbx), "=c" (rcx), + "=d" (rdx), "=S" (rsi), "=D" (rdi) + : "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (in3), + "S" (in4), + "D" (in5) + : "cc", "memory"); + break; + default: + asm_inline volatile ("movw %[port], %%dx; inl (%%dx), %%eax" + : "=a" (out0), "=b" (rbx), "=c" (rcx), + "=d" (rdx), "=S" (rsi), "=D" (rdi) + : [port] "i" (VMWARE_HYPERVISOR_PORT), + "a" (VMWARE_HYPERVISOR_MAGIC), + "b" (in1), + "c" (cmd), + "d" (in3), + "S" (in4), + "D" (in5) + : "cc", "memory"); + break; + } + + if (out1) + *out1 = rbx; + if (out2) + *out2 = rcx; + if (out3) + *out3 = rdx; + if (out4) + *out4 = rsi; + if (out5) + *out5 = rdi; + + return out0; +} + static inline int __vmware_platform(void) { uint32_t eax, ebx, ecx, edx; @@ -480,6 +534,58 @@ (eax & BIT(VMWARE_CMD_LEGACY_X2APIC)); } +#ifdef CONFIG_INTEL_TDX_GUEST +/* + * TDCALL[TDG.VP.VMCALL] uses %rax (arg0) and %rcx (arg2). Therefore, + * we remap those registers to %r12 and %r13, respectively. + */ +unsigned long vmware_tdx_hypercall(unsigned long cmd, + unsigned long in1, unsigned long in3, + unsigned long in4, unsigned long in5, + u32 *out1, u32 *out2, u32 *out3, + u32 *out4, u32 *out5) +{ + struct tdx_module_args args = {}; + + if (!hypervisor_is_type(X86_HYPER_VMWARE)) { + pr_warn_once("Incorrect usage\n"); + return ULONG_MAX; + } + + if (cmd & ~VMWARE_CMD_MASK) { + pr_warn_once("Out of range command %lx\n", cmd); + return ULONG_MAX; + } + + args.rbx = in1; + args.rdx = in3; + args.rsi = in4; + args.rdi = in5; + args.r10 = VMWARE_TDX_VENDOR_LEAF; + args.r11 = VMWARE_TDX_HCALL_FUNC; + args.r12 = VMWARE_HYPERVISOR_MAGIC; + args.r13 = cmd; + /* CPL */ + args.r15 = 0; + + __tdx_hypercall(&args); + + if (out1) + *out1 = args.rbx; + if (out2) + *out2 = args.r13; + if (out3) + *out3 = args.rdx; + if (out4) + *out4 = args.rsi; + if (out5) + *out5 = args.rdi; + + return args.r12; +} +EXPORT_SYMBOL_GPL(vmware_tdx_hypercall); +#endif + #ifdef CONFIG_AMD_MEM_ENCRYPT static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb, struct pt_regs *regs) --- linux-xilinx-6.8.0.orig/arch/x86/kernel/early-quirks.c +++ linux-xilinx-6.8.0/arch/x86/kernel/early-quirks.c @@ -29,6 +29,37 @@ #include #include +static void __init early_pci_clear_msi(int bus, int slot, int func) +{ + int pos; + u16 ctrl; + + if (likely(!pci_early_clear_msi)) + return; + + pr_info_once("Clearing MSI/MSI-X enable bits early in boot (quirk)\n"); + + pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSI); + if (pos) { + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS); + ctrl &= ~PCI_MSI_FLAGS_ENABLE; + write_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS, ctrl); + + /* Read again to flush previous write */ + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS); + } + + pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSIX); + if (pos) { + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS); + ctrl &= ~PCI_MSIX_FLAGS_ENABLE; + write_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS, ctrl); + + /* Read again to flush previous write */ + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS); + } +} + static void __init fix_hypertransport_config(int num, int slot, int func) { u32 htcfg; @@ -728,6 +759,7 @@ PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, { PCI_VENDOR_ID_BROADCOM, 0x4331, PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset}, + { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, early_pci_clear_msi}, {} }; @@ -780,6 +812,10 @@ PCI_HEADER_TYPE); if ((type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) { + /* pci_early_clear_msi scans the buses differently. */ + if (pci_early_clear_msi) + return -1; + sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS); if (sec > num) early_pci_scan_bus(sec); @@ -806,8 +842,13 @@ void __init early_quirks(void) { + int bus; + if (!early_pci_allowed()) return; early_pci_scan_bus(0); + /* pci_early_clear_msi scans more buses. */ + for (bus = 1; pci_early_clear_msi && bus < 256; bus++) + early_pci_scan_bus(bus); } --- linux-xilinx-6.8.0.orig/arch/x86/kernel/eisa.c +++ linux-xilinx-6.8.0/arch/x86/kernel/eisa.c @@ -2,6 +2,7 @@ /* * EISA specific code */ +#include #include #include #include @@ -12,7 +13,7 @@ { void __iomem *p; - if (xen_pv_domain() && !xen_initial_domain()) + if ((xen_pv_domain() && !xen_initial_domain()) || cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) return 0; p = ioremap(0x0FFFD9, 4); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/fpu/core.c +++ linux-xilinx-6.8.0/arch/x86/kernel/fpu/core.c @@ -145,8 +145,8 @@ asm volatile( "fnclex\n\t" "emms\n\t" - "fildl %P[addr]" /* set F?P to defined value */ - : : [addr] "m" (fpstate)); + "fildl %[addr]" /* set F?P to defined value */ + : : [addr] "m" (*fpstate)); } if (use_xsave()) { --- linux-xilinx-6.8.0.orig/arch/x86/kernel/fpu/xstate.c +++ linux-xilinx-6.8.0/arch/x86/kernel/fpu/xstate.c @@ -178,10 +178,11 @@ * Must happen after CR4 setup and before xsetbv() to allow KVM * lazy passthrough. Write independent of the dynamic state static * key as that does not work on the boot CPU. This also ensures - * that any stale state is wiped out from XFD. + * that any stale state is wiped out from XFD. Reset the per CPU + * xfd cache too. */ if (cpu_feature_enabled(X86_FEATURE_XFD)) - wrmsrl(MSR_IA32_XFD, init_fpstate.xfd); + xfd_set_state(init_fpstate.xfd); /* * XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features --- linux-xilinx-6.8.0.orig/arch/x86/kernel/fpu/xstate.h +++ linux-xilinx-6.8.0/arch/x86/kernel/fpu/xstate.h @@ -148,20 +148,26 @@ #endif #ifdef CONFIG_X86_64 +static inline void xfd_set_state(u64 xfd) +{ + wrmsrl(MSR_IA32_XFD, xfd); + __this_cpu_write(xfd_state, xfd); +} + static inline void xfd_update_state(struct fpstate *fpstate) { if (fpu_state_size_dynamic()) { u64 xfd = fpstate->xfd; - if (__this_cpu_read(xfd_state) != xfd) { - wrmsrl(MSR_IA32_XFD, xfd); - __this_cpu_write(xfd_state, xfd); - } + if (__this_cpu_read(xfd_state) != xfd) + xfd_set_state(xfd); } } extern int __xfd_enable_feature(u64 which, struct fpu_guest *guest_fpu); #else +static inline void xfd_set_state(u64 xfd) { } + static inline void xfd_update_state(struct fpstate *fpstate) { } static inline int __xfd_enable_feature(u64 which, struct fpu_guest *guest_fpu) { --- linux-xilinx-6.8.0.orig/arch/x86/kernel/kprobes/core.c +++ linux-xilinx-6.8.0/arch/x86/kernel/kprobes/core.c @@ -335,7 +335,16 @@ kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset, bool *on_func_entry) { - if (is_endbr(*(u32 *)addr)) { + u32 insn; + + /* + * Since 'addr' is not guaranteed to be safe to access, use + * copy_from_kernel_nofault() to read the instruction: + */ + if (copy_from_kernel_nofault(&insn, (void *)addr, sizeof(u32))) + return NULL; + + if (is_endbr(insn)) { *on_func_entry = !offset || offset == 4; if (*on_func_entry) offset = 4; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/kprobes/ftrace.c +++ linux-xilinx-6.8.0/arch/x86/kernel/kprobes/ftrace.c @@ -21,6 +21,9 @@ struct kprobe_ctlblk *kcb; int bit; + if (unlikely(kprobe_ftrace_disabled)) + return; + bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/machine_kexec_64.c +++ linux-xilinx-6.8.0/arch/x86/kernel/machine_kexec_64.c @@ -295,8 +295,15 @@ void machine_kexec(struct kimage *image) { unsigned long page_list[PAGES_NR]; - void *control_page; + unsigned int host_mem_enc_active; int save_ftrace_enabled; + void *control_page; + + /* + * This must be done before load_segments() since if call depth tracking + * is used then GS must be valid to make any function calls. + */ + host_mem_enc_active = cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT); #ifdef CONFIG_KEXEC_JUMP if (image->preserve_context) @@ -358,7 +365,7 @@ (unsigned long)page_list, image->start, image->preserve_context, - cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)); + host_mem_enc_active); #ifdef CONFIG_KEXEC_JUMP if (image->preserve_context) --- linux-xilinx-6.8.0.orig/arch/x86/kernel/nmi.c +++ linux-xilinx-6.8.0/arch/x86/kernel/nmi.c @@ -636,7 +636,7 @@ msgp = nmi_check_stall_msg[idx]; if (nsp->idt_ignored_snap != READ_ONCE(nsp->idt_ignored) && (idx & 0x1)) modp = ", but OK because ignore_nmis was set"; - if (nmi_seq & ~0x1) + if (nmi_seq & 0x1) msghp = " (CPU currently in NMI handler function)"; else if (nsp->idt_nmi_seq_snap + 1 == nmi_seq) msghp = " (CPU exited one NMI handler function)"; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/probe_roms.c +++ linux-xilinx-6.8.0/arch/x86/kernel/probe_roms.c @@ -203,16 +203,6 @@ unsigned char c; int i; - /* - * The ROM memory range is not part of the e820 table and is therefore not - * pre-validated by BIOS. The kernel page table maps the ROM region as encrypted - * memory, and SNP requires encrypted memory to be validated before access. - * Do that here. - */ - snp_prep_memory(video_rom_resource.start, - ((system_rom_resource.end + 1) - video_rom_resource.start), - SNP_PAGE_STATE_PRIVATE); - /* video rom */ upper = adapter_rom_resources[0].start; for (start = video_rom_resource.start; start < upper; start += 2048) { --- linux-xilinx-6.8.0.orig/arch/x86/kernel/process_64.c +++ linux-xilinx-6.8.0/arch/x86/kernel/process_64.c @@ -138,7 +138,7 @@ log_lvl, d3, d6, d7); } - if (cpu_feature_enabled(X86_FEATURE_OSPKE)) + if (cr4 & X86_CR4_PKE) printk("%sPKRU: %08x\n", log_lvl, read_pkru()); } --- linux-xilinx-6.8.0.orig/arch/x86/kernel/reboot.c +++ linux-xilinx-6.8.0/arch/x86/kernel/reboot.c @@ -487,7 +487,46 @@ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), }, }, - + { /* Handle problems with rebooting on the Latitude E6520. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E6520", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6520"), + }, + }, + { /* Handle problems with rebooting on the OptiPlex 790. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 790", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 790"), + }, + }, + { /* Handle problems with rebooting on the OptiPlex 990. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 990", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), + }, + }, + { /* Handle problems with rebooting on the Latitude E6220. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E6220", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6220"), + }, + }, + { /* Handle problems with rebooting on the OptiPlex 390. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 390", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 390"), + }, + }, { } }; --- linux-xilinx-6.8.0.orig/arch/x86/kernel/setup.c +++ linux-xilinx-6.8.0/arch/x86/kernel/setup.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -902,7 +903,15 @@ efi_init(); reserve_ibft_region(); - dmi_setup(); + + efi_set_secure_boot(boot_params.secure_boot); + +#ifdef CONFIG_LOCK_DOWN_IN_SECURE_BOOT + if (efi_enabled(EFI_SECURE_BOOT)) + security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX); +#endif + + x86_init.resources.dmi_setup(); /* * VMware detection requires dmi to be available, so this @@ -994,6 +1003,7 @@ * memory size. */ mem_encrypt_setup_arch(); + cc_random_init(); efi_fake_memmap(); efi_find_mirror(); @@ -1064,19 +1074,7 @@ /* Allocate bigger log buffer */ setup_log_buf(1); - if (efi_enabled(EFI_BOOT)) { - switch (boot_params.secure_boot) { - case efi_secureboot_mode_disabled: - pr_info("Secure boot disabled\n"); - break; - case efi_secureboot_mode_enabled: - pr_info("Secure boot enabled\n"); - break; - default: - pr_info("Secure boot could not be determined\n"); - break; - } - } + efi_set_secure_boot(boot_params.secure_boot); reserve_initrd(); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/sev-shared.c +++ linux-xilinx-6.8.0/arch/x86/kernel/sev-shared.c @@ -10,11 +10,15 @@ */ #ifndef __BOOT_COMPRESSED -#define error(v) pr_err(v) -#define has_cpuflag(f) boot_cpu_has(f) +#define error(v) pr_err(v) +#define has_cpuflag(f) boot_cpu_has(f) +#define sev_printk(fmt, ...) printk(fmt, ##__VA_ARGS__) +#define sev_printk_rtl(fmt, ...) printk_ratelimited(fmt, ##__VA_ARGS__) #else #undef WARN #define WARN(condition, format...) (!!(condition)) +#define sev_printk(fmt, ...) +#define sev_printk_rtl(fmt, ...) #endif /* I/O parameters for CPUID-related helpers */ @@ -89,7 +93,8 @@ return true; } -static void __noreturn sev_es_terminate(unsigned int set, unsigned int reason) +static void __head __noreturn +sev_es_terminate(unsigned int set, unsigned int reason) { u64 val = GHCB_MSR_TERM_REQ; @@ -326,13 +331,7 @@ */ static const struct snp_cpuid_table *snp_cpuid_get_table(void) { - void *ptr; - - asm ("lea cpuid_table_copy(%%rip), %0" - : "=r" (ptr) - : "p" (&cpuid_table_copy)); - - return ptr; + return &RIP_REL_REF(cpuid_table_copy); } /* @@ -391,7 +390,7 @@ return xsave_size; } -static bool +static bool __head snp_cpuid_get_validated_func(struct cpuid_leaf *leaf) { const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); @@ -528,7 +527,8 @@ * Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value * should be treated as fatal by caller. */ -static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) +static int __head +snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) { const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); @@ -556,9 +556,9 @@ leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0; /* Skip post-processing for out-of-range zero leafs. */ - if (!(leaf->fn <= cpuid_std_range_max || - (leaf->fn >= 0x40000000 && leaf->fn <= cpuid_hyp_range_max) || - (leaf->fn >= 0x80000000 && leaf->fn <= cpuid_ext_range_max))) + if (!(leaf->fn <= RIP_REL_REF(cpuid_std_range_max) || + (leaf->fn >= 0x40000000 && leaf->fn <= RIP_REL_REF(cpuid_hyp_range_max)) || + (leaf->fn >= 0x80000000 && leaf->fn <= RIP_REL_REF(cpuid_ext_range_max)))) return 0; } @@ -570,10 +570,11 @@ * page yet, so it only supports the MSR based communication with the * hypervisor and only the CPUID exit-code. */ -void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) +void __head do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code) { unsigned int subfn = lower_bits(regs->cx, 32); unsigned int fn = lower_bits(regs->ax, 32); + u16 opcode = *(unsigned short *)regs->ip; struct cpuid_leaf leaf; int ret; @@ -581,6 +582,10 @@ if (exit_code != SVM_EXIT_CPUID) goto fail; + /* Is it really a CPUID insn? */ + if (opcode != 0xa20f) + goto fail; + leaf.fn = fn; leaf.subfn = subfn; @@ -1016,7 +1021,8 @@ * Search for a Confidential Computing blob passed in as a setup_data entry * via the Linux Boot Protocol. */ -static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp) +static __head +struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp) { struct cc_setup_data *sd = NULL; struct setup_data *hdr; @@ -1043,7 +1049,7 @@ * mapping needs to be updated in sync with all the changes to virtual memory * layout and related mapping facilities throughout the boot process. */ -static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info) +static void __head setup_cpuid_table(const struct cc_blob_sev_info *cc_info) { const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table; int i; @@ -1063,11 +1069,11 @@ const struct snp_cpuid_fn *fn = &cpuid_table->fn[i]; if (fn->eax_in == 0x0) - cpuid_std_range_max = fn->eax; + RIP_REL_REF(cpuid_std_range_max) = fn->eax; else if (fn->eax_in == 0x40000000) - cpuid_hyp_range_max = fn->eax; + RIP_REL_REF(cpuid_hyp_range_max) = fn->eax; else if (fn->eax_in == 0x80000000) - cpuid_ext_range_max = fn->eax; + RIP_REL_REF(cpuid_ext_range_max) = fn->eax; } } @@ -1170,3 +1176,94 @@ out: return ret; } + +static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt, + unsigned long exit_code) +{ + unsigned int opcode = (unsigned int)ctxt->insn.opcode.value; + u8 modrm = ctxt->insn.modrm.value; + + switch (exit_code) { + + case SVM_EXIT_IOIO: + case SVM_EXIT_NPF: + /* handled separately */ + return ES_OK; + + case SVM_EXIT_CPUID: + if (opcode == 0xa20f) + return ES_OK; + break; + + case SVM_EXIT_INVD: + if (opcode == 0x080f) + return ES_OK; + break; + + case SVM_EXIT_MONITOR: + /* MONITOR and MONITORX instructions generate the same error code */ + if (opcode == 0x010f && (modrm == 0xc8 || modrm == 0xfa)) + return ES_OK; + break; + + case SVM_EXIT_MWAIT: + /* MWAIT and MWAITX instructions generate the same error code */ + if (opcode == 0x010f && (modrm == 0xc9 || modrm == 0xfb)) + return ES_OK; + break; + + case SVM_EXIT_MSR: + /* RDMSR */ + if (opcode == 0x320f || + /* WRMSR */ + opcode == 0x300f) + return ES_OK; + break; + + case SVM_EXIT_RDPMC: + if (opcode == 0x330f) + return ES_OK; + break; + + case SVM_EXIT_RDTSC: + if (opcode == 0x310f) + return ES_OK; + break; + + case SVM_EXIT_RDTSCP: + if (opcode == 0x010f && modrm == 0xf9) + return ES_OK; + break; + + case SVM_EXIT_READ_DR7: + if (opcode == 0x210f && + X86_MODRM_REG(ctxt->insn.modrm.value) == 7) + return ES_OK; + break; + + case SVM_EXIT_VMMCALL: + if (opcode == 0x010f && modrm == 0xd9) + return ES_OK; + + break; + + case SVM_EXIT_WRITE_DR7: + if (opcode == 0x230f && + X86_MODRM_REG(ctxt->insn.modrm.value) == 7) + return ES_OK; + break; + + case SVM_EXIT_WBINVD: + if (opcode == 0x90f) + return ES_OK; + break; + + default: + break; + } + + sev_printk(KERN_ERR "Wrong/unhandled opcode bytes: 0x%x, exit_code: 0x%lx, rIP: 0x%lx\n", + opcode, exit_code, ctxt->regs->ip); + + return ES_UNSUPPORTED; +} --- linux-xilinx-6.8.0.orig/arch/x86/kernel/sev.c +++ linux-xilinx-6.8.0/arch/x86/kernel/sev.c @@ -23,8 +23,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -682,8 +684,9 @@ return ret; } -static void early_set_pages_state(unsigned long vaddr, unsigned long paddr, - unsigned long npages, enum psc_op op) +static void __head +early_set_pages_state(unsigned long vaddr, unsigned long paddr, + unsigned long npages, enum psc_op op) { unsigned long paddr_end; u64 val; @@ -739,7 +742,7 @@ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC); } -void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, +void __head early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { /* @@ -748,7 +751,7 @@ * This eliminates worries about jump tables or checking boot_cpu_data * in the cc_platform_has() function. */ - if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) + if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED)) return; /* @@ -767,28 +770,13 @@ * This eliminates worries about jump tables or checking boot_cpu_data * in the cc_platform_has() function. */ - if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) + if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED)) return; /* Ask hypervisor to mark the memory pages shared in the RMP table. */ early_set_pages_state(vaddr, paddr, npages, SNP_PAGE_STATE_SHARED); } -void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) -{ - unsigned long vaddr, npages; - - vaddr = (unsigned long)__va(paddr); - npages = PAGE_ALIGN(sz) >> PAGE_SHIFT; - - if (op == SNP_PAGE_STATE_PRIVATE) - early_snp_set_memory_private(vaddr, paddr, npages); - else if (op == SNP_PAGE_STATE_SHARED) - early_snp_set_memory_shared(vaddr, paddr, npages); - else - WARN(1, "invalid memory op %d\n", op); -} - static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr, unsigned long vaddr_end, int op) { @@ -1752,7 +1740,10 @@ struct ghcb *ghcb, unsigned long exit_code) { - enum es_result result; + enum es_result result = vc_check_opcode_bytes(ctxt, exit_code); + + if (result != ES_OK) + return result; switch (exit_code) { case SVM_EXIT_READ_DR7: @@ -2059,7 +2050,7 @@ * * Scan for the blob in that order. */ -static __init struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp) +static __head struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp) { struct cc_blob_sev_info *cc_info; @@ -2085,7 +2076,7 @@ return cc_info; } -bool __init snp_init(struct boot_params *bp) +bool __head snp_init(struct boot_params *bp) { struct cc_blob_sev_info *cc_info; @@ -2107,11 +2098,22 @@ return true; } -void __init __noreturn snp_abort(void) +void __head __noreturn snp_abort(void) { sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); } +/* + * SEV-SNP guests should only execute dmi_setup() if EFI_CONFIG_TABLES are + * enabled, as the alternative (fallback) logic for DMI probing in the legacy + * ROM region can cause a crash since this region is not pre-validated. + */ +void __init snp_dmi_setup(void) +{ + if (efi_enabled(EFI_CONFIG_TABLES)) + dmi_setup(); +} + static void dump_cpuid_table(void) { const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/time.c +++ linux-xilinx-6.8.0/arch/x86/kernel/time.c @@ -27,25 +27,7 @@ unsigned long profile_pc(struct pt_regs *regs) { - unsigned long pc = instruction_pointer(regs); - - if (!user_mode(regs) && in_lock_functions(pc)) { -#ifdef CONFIG_FRAME_POINTER - return *(unsigned long *)(regs->bp + sizeof(long)); -#else - unsigned long *sp = (unsigned long *)regs->sp; - /* - * Return address is either directly at stack pointer - * or above a saved flags. Eflags has bits 22-31 zero, - * kernel addresses don't. - */ - if (sp[0] >> 22) - return sp[0]; - if (sp[1] >> 22) - return sp[1]; -#endif - } - return pc; + return instruction_pointer(regs); } EXPORT_SYMBOL(profile_pc); --- linux-xilinx-6.8.0.orig/arch/x86/kernel/tsc_sync.c +++ linux-xilinx-6.8.0/arch/x86/kernel/tsc_sync.c @@ -193,11 +193,9 @@ cur->warned = false; /* - * If a non-zero TSC value for socket 0 may be valid then the default - * adjusted value cannot assumed to be zero either. + * The default adjust value cannot be assumed to be zero on any socket. */ - if (tsc_async_resets) - cur->adjusted = bootval; + cur->adjusted = bootval; /* * Check whether this CPU is the first in a package to come up. In --- linux-xilinx-6.8.0.orig/arch/x86/kernel/x86_init.c +++ linux-xilinx-6.8.0/arch/x86/kernel/x86_init.c @@ -3,6 +3,7 @@ * * For licencing details see kernel-base/COPYING */ +#include #include #include #include @@ -66,6 +67,7 @@ .probe_roms = probe_roms, .reserve_resources = reserve_standard_io_resources, .memory_setup = e820__memory_setup_default, + .dmi_setup = dmi_setup, }, .mpparse = { --- linux-xilinx-6.8.0.orig/arch/x86/kvm/cpuid.c +++ linux-xilinx-6.8.0/arch/x86/kvm/cpuid.c @@ -366,6 +366,7 @@ kvm_update_pv_runtime(vcpu); + vcpu->arch.is_amd_compatible = guest_cpuid_is_amd_or_hygon(vcpu); vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu); vcpu->arch.reserved_gpa_bits = kvm_vcpu_reserved_gpa_bits_raw(vcpu); @@ -1221,9 +1222,8 @@ entry->eax = entry->ebx = entry->ecx = 0; break; case 0x80000008: { - unsigned g_phys_as = (entry->eax >> 16) & 0xff; - unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U); - unsigned phys_as = entry->eax & 0xff; + unsigned int virt_as = max((entry->eax >> 8) & 0xff, 48U); + unsigned int phys_as; /* * If TDP (NPT) is disabled use the adjusted host MAXPHYADDR as @@ -1231,16 +1231,16 @@ * reductions in MAXPHYADDR for memory encryption affect shadow * paging, too. * - * If TDP is enabled but an explicit guest MAXPHYADDR is not - * provided, use the raw bare metal MAXPHYADDR as reductions to - * the HPAs do not affect GPAs. + * If TDP is enabled, use the raw bare metal MAXPHYADDR as + * reductions to the HPAs do not affect GPAs. */ - if (!tdp_enabled) - g_phys_as = boot_cpu_data.x86_phys_bits; - else if (!g_phys_as) - g_phys_as = phys_as; + if (!tdp_enabled) { + phys_as = boot_cpu_data.x86_phys_bits; + } else { + phys_as = entry->eax & 0xff; + } - entry->eax = g_phys_as | (virt_as << 8); + entry->eax = phys_as | (virt_as << 8); entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8)); entry->edx = 0; cpuid_entry_override(entry, CPUID_8000_0008_EBX); --- linux-xilinx-6.8.0.orig/arch/x86/kvm/cpuid.h +++ linux-xilinx-6.8.0/arch/x86/kvm/cpuid.h @@ -120,6 +120,16 @@ return best && is_guest_vendor_intel(best->ebx, best->ecx, best->edx); } +static inline bool guest_cpuid_is_amd_compatible(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.is_amd_compatible; +} + +static inline bool guest_cpuid_is_intel_compatible(struct kvm_vcpu *vcpu) +{ + return !guest_cpuid_is_amd_compatible(vcpu); +} + static inline int guest_cpuid_family(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; --- linux-xilinx-6.8.0.orig/arch/x86/kvm/lapic.c +++ linux-xilinx-6.8.0/arch/x86/kvm/lapic.c @@ -41,6 +41,7 @@ #include "ioapic.h" #include "trace.h" #include "x86.h" +#include "xen.h" #include "cpuid.h" #include "hyperv.h" #include "smm.h" @@ -499,8 +500,10 @@ } /* Check if there are APF page ready requests pending */ - if (enabled) + if (enabled) { kvm_make_request(KVM_REQ_APF_READY, apic->vcpu); + kvm_xen_sw_enable_lapic(apic->vcpu); + } } static inline void kvm_apic_set_xapic_id(struct kvm_lapic *apic, u8 id) @@ -2768,7 +2771,8 @@ trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; r = __apic_accept_irq(apic, mode, vector, 1, trig_mode, NULL); - if (r && lvt_type == APIC_LVTPC) + if (r && lvt_type == APIC_LVTPC && + guest_cpuid_is_intel_compatible(apic->vcpu)) kvm_lapic_set_reg(apic, APIC_LVTPC, reg | APIC_LVT_MASKED); return r; } --- linux-xilinx-6.8.0.orig/arch/x86/kvm/mmu/mmu.c +++ linux-xilinx-6.8.0/arch/x86/kvm/mmu/mmu.c @@ -3126,7 +3126,7 @@ if (pud_none(pud) || !pud_present(pud)) goto out; - if (pud_large(pud)) { + if (pud_leaf(pud)) { level = PG_LEVEL_1G; goto out; } @@ -4922,7 +4922,7 @@ context->cpu_role.base.level, is_efer_nx(context), guest_can_use(vcpu, X86_FEATURE_GBPAGES), is_cr4_pse(context), - guest_cpuid_is_amd_or_hygon(vcpu)); + guest_cpuid_is_amd_compatible(vcpu)); } static void __reset_rsvds_bits_mask_ept(struct rsvd_bits_validate *rsvd_check, @@ -7388,7 +7388,8 @@ * by the memslot, KVM can't use a hugepage due to the * misaligned address regardless of memory attributes. */ - if (gfn >= slot->base_gfn) { + if (gfn >= slot->base_gfn && + gfn + nr_pages <= slot->base_gfn + slot->npages) { if (hugepage_has_attrs(kvm, slot, gfn, level, attrs)) hugepage_clear_mixed(slot, gfn, level); else --- linux-xilinx-6.8.0.orig/arch/x86/kvm/mmu/tdp_mmu.c +++ linux-xilinx-6.8.0/arch/x86/kvm/mmu/tdp_mmu.c @@ -1498,6 +1498,16 @@ } } +static bool tdp_mmu_need_write_protect(struct kvm_mmu_page *sp) +{ + /* + * All TDP MMU shadow pages share the same role as their root, aside + * from level, so it is valid to key off any shadow page to determine if + * write protection is needed for an entire tree. + */ + return kvm_mmu_page_ad_need_write_protect(sp) || !kvm_ad_enabled(); +} + /* * Clear the dirty status of all the SPTEs mapping GFNs in the memslot. If * AD bits are enabled, this will involve clearing the dirty bit on each SPTE. @@ -1508,7 +1518,8 @@ static bool clear_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root, gfn_t start, gfn_t end) { - u64 dbit = kvm_ad_enabled() ? shadow_dirty_mask : PT_WRITABLE_MASK; + const u64 dbit = tdp_mmu_need_write_protect(root) ? PT_WRITABLE_MASK : + shadow_dirty_mask; struct tdp_iter iter; bool spte_set = false; @@ -1523,7 +1534,7 @@ if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true)) continue; - KVM_MMU_WARN_ON(kvm_ad_enabled() && + KVM_MMU_WARN_ON(dbit == shadow_dirty_mask && spte_ad_need_write_protect(iter.old_spte)); if (!(iter.old_spte & dbit)) @@ -1570,8 +1581,8 @@ static void clear_dirty_pt_masked(struct kvm *kvm, struct kvm_mmu_page *root, gfn_t gfn, unsigned long mask, bool wrprot) { - u64 dbit = (wrprot || !kvm_ad_enabled()) ? PT_WRITABLE_MASK : - shadow_dirty_mask; + const u64 dbit = (wrprot || tdp_mmu_need_write_protect(root)) ? PT_WRITABLE_MASK : + shadow_dirty_mask; struct tdp_iter iter; lockdep_assert_held_write(&kvm->mmu_lock); @@ -1583,7 +1594,7 @@ if (!mask) break; - KVM_MMU_WARN_ON(kvm_ad_enabled() && + KVM_MMU_WARN_ON(dbit == shadow_dirty_mask && spte_ad_need_write_protect(iter.old_spte)); if (iter.level > PG_LEVEL_4K || --- linux-xilinx-6.8.0.orig/arch/x86/kvm/pmu.c +++ linux-xilinx-6.8.0/arch/x86/kvm/pmu.c @@ -741,6 +741,8 @@ */ void kvm_pmu_refresh(struct kvm_vcpu *vcpu) { + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm)) return; @@ -750,8 +752,34 @@ */ kvm_pmu_reset(vcpu); - bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX); + pmu->version = 0; + pmu->nr_arch_gp_counters = 0; + pmu->nr_arch_fixed_counters = 0; + pmu->counter_bitmask[KVM_PMC_GP] = 0; + pmu->counter_bitmask[KVM_PMC_FIXED] = 0; + pmu->reserved_bits = 0xffffffff00200000ull; + pmu->raw_event_mask = X86_RAW_EVENT_MASK; + pmu->global_ctrl_mask = ~0ull; + pmu->global_status_mask = ~0ull; + pmu->fixed_ctr_ctrl_mask = ~0ull; + pmu->pebs_enable_mask = ~0ull; + pmu->pebs_data_cfg_mask = ~0ull; + bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX); + + if (!vcpu->kvm->arch.enable_pmu) + return; + static_call(kvm_x86_pmu_refresh)(vcpu); + + /* + * At RESET, both Intel and AMD CPUs set all enable bits for general + * purpose counters in IA32_PERF_GLOBAL_CTRL (so that software that + * was written for v1 PMUs don't unknowingly leave GP counters disabled + * in the global controls). Emulate that behavior when refreshing the + * PMU so that userspace doesn't need to manually set PERF_GLOBAL_CTRL. + */ + if (kvm_pmu_has_perf_global_ctrl(pmu) && pmu->nr_arch_gp_counters) + pmu->global_ctrl = GENMASK_ULL(pmu->nr_arch_gp_counters - 1, 0); } void kvm_pmu_init(struct kvm_vcpu *vcpu) --- linux-xilinx-6.8.0.orig/arch/x86/kvm/reverse_cpuid.h +++ linux-xilinx-6.8.0/arch/x86/kvm/reverse_cpuid.h @@ -52,7 +52,7 @@ #define X86_FEATURE_IPRED_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 1) #define KVM_X86_FEATURE_RRSBA_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 2) #define X86_FEATURE_DDPD_U KVM_X86_FEATURE(CPUID_7_2_EDX, 3) -#define X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4) +#define KVM_X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4) #define X86_FEATURE_MCDT_NO KVM_X86_FEATURE(CPUID_7_2_EDX, 5) /* CPUID level 0x80000007 (EDX). */ @@ -102,10 +102,12 @@ */ static __always_inline void reverse_cpuid_check(unsigned int x86_leaf) { + BUILD_BUG_ON(NR_CPUID_WORDS != NCAPINTS); BUILD_BUG_ON(x86_leaf == CPUID_LNX_1); BUILD_BUG_ON(x86_leaf == CPUID_LNX_2); BUILD_BUG_ON(x86_leaf == CPUID_LNX_3); BUILD_BUG_ON(x86_leaf == CPUID_LNX_4); + BUILD_BUG_ON(x86_leaf == CPUID_LNX_5); BUILD_BUG_ON(x86_leaf >= ARRAY_SIZE(reverse_cpuid)); BUILD_BUG_ON(reverse_cpuid[x86_leaf].function == 0); } @@ -126,6 +128,7 @@ KVM_X86_TRANSLATE_FEATURE(CONSTANT_TSC); KVM_X86_TRANSLATE_FEATURE(PERFMON_V2); KVM_X86_TRANSLATE_FEATURE(RRSBA_CTRL); + KVM_X86_TRANSLATE_FEATURE(BHI_CTRL); default: return x86_feature; } --- linux-xilinx-6.8.0.orig/arch/x86/kvm/svm/sev.c +++ linux-xilinx-6.8.0/arch/x86/kvm/svm/sev.c @@ -84,9 +84,10 @@ }; /* Called with the sev_bitmap_lock held, or on shutdown */ -static int sev_flush_asids(int min_asid, int max_asid) +static int sev_flush_asids(unsigned int min_asid, unsigned int max_asid) { - int ret, asid, error = 0; + int ret, error = 0; + unsigned int asid; /* Check if there are any ASIDs to reclaim before performing a flush */ asid = find_next_bit(sev_reclaim_asid_bitmap, nr_asids, min_asid); @@ -116,7 +117,7 @@ } /* Must be called with the sev_bitmap_lock held */ -static bool __sev_recycle_asids(int min_asid, int max_asid) +static bool __sev_recycle_asids(unsigned int min_asid, unsigned int max_asid) { if (sev_flush_asids(min_asid, max_asid)) return false; @@ -143,8 +144,20 @@ static int sev_asid_new(struct kvm_sev_info *sev) { - int asid, min_asid, max_asid, ret; + /* + * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid. + * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1. + * Note: min ASID can end up larger than the max if basic SEV support is + * effectively disabled by disallowing use of ASIDs for SEV guests. + */ + unsigned int min_asid = sev->es_active ? 1 : min_sev_asid; + unsigned int max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid; + unsigned int asid; bool retry = true; + int ret; + + if (min_asid > max_asid) + return -ENOTTY; WARN_ON(sev->misc_cg); sev->misc_cg = get_current_misc_cg(); @@ -157,12 +170,6 @@ mutex_lock(&sev_bitmap_lock); - /* - * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid. - * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1. - */ - min_asid = sev->es_active ? 1 : min_sev_asid; - max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid; again: asid = find_next_zero_bit(sev_asid_bitmap, max_asid + 1, min_asid); if (asid > max_asid) { @@ -187,7 +194,7 @@ return ret; } -static int sev_get_asid(struct kvm *kvm) +static unsigned int sev_get_asid(struct kvm *kvm) { struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; @@ -284,8 +291,8 @@ static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) { + unsigned int asid = sev_get_asid(kvm); struct sev_data_activate activate; - int asid = sev_get_asid(kvm); int ret; /* activate ASID on the given handle */ @@ -657,6 +664,14 @@ return ret; vcpu->arch.guest_state_protected = true; + + /* + * SEV-ES guest mandates LBR Virtualization to be _always_ ON. Enable it + * only after setting guest_state_protected because KVM_SET_MSRS allows + * dynamic toggling of LBRV (for performance reason) on write access to + * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set. + */ + svm_enable_lbrv(vcpu); return 0; } @@ -2237,8 +2252,10 @@ goto out; } - sev_asid_count = max_sev_asid - min_sev_asid + 1; - WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count)); + if (min_sev_asid <= max_sev_asid) { + sev_asid_count = max_sev_asid - min_sev_asid + 1; + WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count)); + } sev_supported = true; /* SEV-ES support requested? */ @@ -2258,6 +2275,12 @@ if (!boot_cpu_has(X86_FEATURE_SEV_ES)) goto out; + if (!lbrv) { + WARN_ONCE(!boot_cpu_has(X86_FEATURE_LBRV), + "LBRV must be present for SEV-ES support"); + goto out; + } + /* Has the system been allocated ASIDs for SEV-ES? */ if (min_sev_asid == 1) goto out; @@ -2269,7 +2292,9 @@ out: if (boot_cpu_has(X86_FEATURE_SEV)) pr_info("SEV %s (ASIDs %u - %u)\n", - sev_supported ? "enabled" : "disabled", + sev_supported ? min_sev_asid <= max_sev_asid ? "enabled" : + "unusable" : + "disabled", min_sev_asid, max_sev_asid); if (boot_cpu_has(X86_FEATURE_SEV_ES)) pr_info("SEV-ES %s (ASIDs %u - %u)\n", @@ -2317,7 +2342,7 @@ */ static void sev_flush_encrypted_page(struct kvm_vcpu *vcpu, void *va) { - int asid = to_kvm_svm(vcpu->kvm)->sev_info.asid; + unsigned int asid = sev_get_asid(vcpu->kvm); /* * Note! The address must be a kernel address, as regular page walk @@ -2635,7 +2660,7 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu) { struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); - int asid = sev_get_asid(svm->vcpu.kvm); + unsigned int asid = sev_get_asid(svm->vcpu.kvm); /* Assign the asid allocated with this SEV guest */ svm->asid = asid; @@ -3021,7 +3046,6 @@ struct kvm_vcpu *vcpu = &svm->vcpu; svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE; - svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK; /* * An SEV-ES guest requires a VMSA area that is a separate from the @@ -3073,10 +3097,6 @@ /* Clear intercepts on selected MSRs */ set_msr_interception(vcpu, svm->msrpm, MSR_EFER, 1, 1); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_CR_PAT, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); - set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); } void sev_init_vmcb(struct vcpu_svm *svm) --- linux-xilinx-6.8.0.orig/arch/x86/kvm/svm/svm.c +++ linux-xilinx-6.8.0/arch/x86/kvm/svm/svm.c @@ -99,6 +99,7 @@ { .index = MSR_IA32_SPEC_CTRL, .always = false }, { .index = MSR_IA32_PRED_CMD, .always = false }, { .index = MSR_IA32_FLUSH_CMD, .always = false }, + { .index = MSR_IA32_DEBUGCTLMSR, .always = false }, { .index = MSR_IA32_LASTBRANCHFROMIP, .always = false }, { .index = MSR_IA32_LASTBRANCHTOIP, .always = false }, { .index = MSR_IA32_LASTINTFROMIP, .always = false }, @@ -215,7 +216,7 @@ module_param(vgif, int, 0444); /* enable/disable LBR virtualization */ -static int lbrv = true; +int lbrv = true; module_param(lbrv, int, 0444); static int tsc_scaling = true; @@ -990,7 +991,7 @@ vmcb_mark_dirty(to_vmcb, VMCB_LBR); } -static void svm_enable_lbrv(struct kvm_vcpu *vcpu) +void svm_enable_lbrv(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1000,6 +1001,9 @@ set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); + if (sev_es_guest(vcpu->kvm)) + set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, 1, 1); + /* Move the LBR msrs to the vmcb02 so that the guest can see them. */ if (is_guest_mode(vcpu)) svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr); @@ -1009,6 +1013,8 @@ { struct vcpu_svm *svm = to_svm(vcpu); + KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm); + svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK; set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0); @@ -3845,16 +3851,27 @@ struct vcpu_svm *svm = to_svm(vcpu); /* - * KVM should never request an NMI window when vNMI is enabled, as KVM - * allows at most one to-be-injected NMI and one pending NMI, i.e. if - * two NMIs arrive simultaneously, KVM will inject one and set - * V_NMI_PENDING for the other. WARN, but continue with the standard - * single-step approach to try and salvage the pending NMI. + * If NMIs are outright masked, i.e. the vCPU is already handling an + * NMI, and KVM has not yet intercepted an IRET, then there is nothing + * more to do at this time as KVM has already enabled IRET intercepts. + * If KVM has already intercepted IRET, then single-step over the IRET, + * as NMIs aren't architecturally unmasked until the IRET completes. + * + * If vNMI is enabled, KVM should never request an NMI window if NMIs + * are masked, as KVM allows at most one to-be-injected NMI and one + * pending NMI. If two NMIs arrive simultaneously, KVM will inject one + * NMI and set V_NMI_PENDING for the other, but if and only if NMIs are + * unmasked. KVM _will_ request an NMI window in some situations, e.g. + * if the vCPU is in an STI shadow or if GIF=0, KVM can't immediately + * inject the NMI. In those situations, KVM needs to single-step over + * the STI shadow or intercept STGI. */ - WARN_ON_ONCE(is_vnmi_enabled(svm)); + if (svm_get_nmi_mask(vcpu)) { + WARN_ON_ONCE(is_vnmi_enabled(svm)); - if (svm_get_nmi_mask(vcpu) && !svm->awaiting_iret_completion) - return; /* IRET will cause a vm exit */ + if (!svm->awaiting_iret_completion) + return; /* IRET will cause a vm exit */ + } /* * SEV-ES guests are responsible for signaling when a vCPU is ready to @@ -5236,6 +5253,12 @@ nrips = nrips && boot_cpu_has(X86_FEATURE_NRIPS); + if (lbrv) { + if (!boot_cpu_has(X86_FEATURE_LBRV)) + lbrv = false; + else + pr_info("LBR virtualization supported\n"); + } /* * Note, SEV setup consumes npt_enabled and enable_mmio_caching (which * may be modified by svm_adjust_mmio_mask()), as well as nrips. @@ -5289,14 +5312,6 @@ svm_x86_ops.set_vnmi_pending = NULL; } - - if (lbrv) { - if (!boot_cpu_has(X86_FEATURE_LBRV)) - lbrv = false; - else - pr_info("LBR virtualization supported\n"); - } - if (!enable_pmu) pr_info("PMU virtualization is disabled\n"); --- linux-xilinx-6.8.0.orig/arch/x86/kvm/svm/svm.h +++ linux-xilinx-6.8.0/arch/x86/kvm/svm/svm.h @@ -30,7 +30,7 @@ #define IOPM_SIZE PAGE_SIZE * 3 #define MSRPM_SIZE PAGE_SIZE * 2 -#define MAX_DIRECT_ACCESS_MSRS 47 +#define MAX_DIRECT_ACCESS_MSRS 48 #define MSRPM_OFFSETS 32 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; extern bool npt_enabled; @@ -39,6 +39,7 @@ extern bool intercept_smi; extern bool x2avic_enabled; extern bool vnmi; +extern int lbrv; /* * Clean bits in VMCB. @@ -543,6 +544,7 @@ void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm); void svm_vcpu_free_msrpm(u32 *msrpm); void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb); +void svm_enable_lbrv(struct kvm_vcpu *vcpu); void svm_update_lbrv(struct kvm_vcpu *vcpu); int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer); --- linux-xilinx-6.8.0.orig/arch/x86/kvm/trace.h +++ linux-xilinx-6.8.0/arch/x86/kvm/trace.h @@ -732,13 +732,13 @@ * Tracepoint for nested #vmexit because of interrupt pending */ TRACE_EVENT(kvm_invlpga, - TP_PROTO(__u64 rip, int asid, u64 address), + TP_PROTO(__u64 rip, unsigned int asid, u64 address), TP_ARGS(rip, asid, address), TP_STRUCT__entry( - __field( __u64, rip ) - __field( int, asid ) - __field( __u64, address ) + __field( __u64, rip ) + __field( unsigned int, asid ) + __field( __u64, address ) ), TP_fast_assign( @@ -747,7 +747,7 @@ __entry->address = address; ), - TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx", + TP_printk("rip: 0x%016llx asid: %u address: 0x%016llx", __entry->rip, __entry->asid, __entry->address) ); --- linux-xilinx-6.8.0.orig/arch/x86/kvm/vmx/pmu_intel.c +++ linux-xilinx-6.8.0/arch/x86/kvm/vmx/pmu_intel.c @@ -491,19 +491,6 @@ u64 counter_mask; int i; - pmu->nr_arch_gp_counters = 0; - pmu->nr_arch_fixed_counters = 0; - pmu->counter_bitmask[KVM_PMC_GP] = 0; - pmu->counter_bitmask[KVM_PMC_FIXED] = 0; - pmu->version = 0; - pmu->reserved_bits = 0xffffffff00200000ull; - pmu->raw_event_mask = X86_RAW_EVENT_MASK; - pmu->global_ctrl_mask = ~0ull; - pmu->global_status_mask = ~0ull; - pmu->fixed_ctr_ctrl_mask = ~0ull; - pmu->pebs_enable_mask = ~0ull; - pmu->pebs_data_cfg_mask = ~0ull; - memset(&lbr_desc->records, 0, sizeof(lbr_desc->records)); /* @@ -515,8 +502,9 @@ return; entry = kvm_find_cpuid_entry(vcpu, 0xa); - if (!entry || !vcpu->kvm->arch.enable_pmu) + if (!entry) return; + eax.full = entry->eax; edx.full = entry->edx; --- linux-xilinx-6.8.0.orig/arch/x86/kvm/vmx/vmenter.S +++ linux-xilinx-6.8.0/arch/x86/kvm/vmx/vmenter.S @@ -275,6 +275,8 @@ call vmx_spec_ctrl_restore_host + CLEAR_BRANCH_HISTORY_VMEXIT + /* Put return value in AX */ mov %_ASM_BX, %_ASM_AX --- linux-xilinx-6.8.0.orig/arch/x86/kvm/vmx/vmx.c +++ linux-xilinx-6.8.0/arch/x86/kvm/vmx/vmx.c @@ -7857,8 +7857,28 @@ if (vmx_pebs_supported()) { perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK; - if ((perf_cap & PERF_CAP_PEBS_FORMAT) < 4) - perf_cap &= ~PERF_CAP_PEBS_BASELINE; + + /* + * Disallow adaptive PEBS as it is functionally broken, can be + * used by the guest to read *host* LBRs, and can be used to + * bypass userspace event filters. To correctly and safely + * support adaptive PEBS, KVM needs to: + * + * 1. Account for the ADAPTIVE flag when (re)programming fixed + * counters. + * + * 2. Gain support from perf (or take direct control of counter + * programming) to support events without adaptive PEBS + * enabled for the hardware counter. + * + * 3. Ensure LBR MSRs cannot hold host data on VM-Entry with + * adaptive PEBS enabled and MSR_PEBS_DATA_CFG.LBRS=1. + * + * 4. Document which PMU events are effectively exposed to the + * guest via adaptive PEBS, and make adaptive PEBS mutually + * exclusive with KVM_SET_PMU_EVENT_FILTER if necessary. + */ + perf_cap &= ~PERF_CAP_PEBS_BASELINE; } return perf_cap; --- linux-xilinx-6.8.0.orig/arch/x86/kvm/x86.c +++ linux-xilinx-6.8.0/arch/x86/kvm/x86.c @@ -1623,7 +1623,8 @@ ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \ ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ - ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO) + ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \ + ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO) static u64 kvm_get_arch_capabilities(void) { @@ -1655,6 +1656,8 @@ data |= ARCH_CAP_SSB_NO; if (!boot_cpu_has_bug(X86_BUG_MDS)) data |= ARCH_CAP_MDS_NO; + if (!boot_cpu_has_bug(X86_BUG_RFDS)) + data |= ARCH_CAP_RFDS_NO; if (!boot_cpu_has(X86_FEATURE_RTM)) { /* @@ -3419,7 +3422,7 @@ static bool can_set_mci_status(struct kvm_vcpu *vcpu) { /* McStatusWrEn enabled? */ - if (guest_cpuid_is_amd_or_hygon(vcpu)) + if (guest_cpuid_is_amd_compatible(vcpu)) return !!(vcpu->arch.msr_hwcr & BIT_ULL(18)); return false; @@ -10639,13 +10642,12 @@ bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256); + static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); + if (irqchip_split(vcpu->kvm)) kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); - else { - static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu); - if (ioapic_in_kernel(vcpu->kvm)) - kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); - } + else if (ioapic_in_kernel(vcpu->kvm)) + kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); if (is_guest_mode(vcpu)) vcpu->arch.load_eoi_exitmap_pending = true; --- linux-xilinx-6.8.0.orig/arch/x86/kvm/xen.c +++ linux-xilinx-6.8.0/arch/x86/kvm/xen.c @@ -493,7 +493,7 @@ kvm_xen_update_runstate_guest(v, state == RUNSTATE_runnable); } -static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) +void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v) { struct kvm_lapic_irq irq = { }; int r; --- linux-xilinx-6.8.0.orig/arch/x86/kvm/xen.h +++ linux-xilinx-6.8.0/arch/x86/kvm/xen.h @@ -18,6 +18,7 @@ int __kvm_xen_has_interrupt(struct kvm_vcpu *vcpu); void kvm_xen_inject_pending_events(struct kvm_vcpu *vcpu); +void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *vcpu); int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data); int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data); int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data); @@ -36,6 +37,19 @@ const struct kvm_irq_routing_entry *ue); void kvm_xen_update_tsc_info(struct kvm_vcpu *vcpu); +static inline void kvm_xen_sw_enable_lapic(struct kvm_vcpu *vcpu) +{ + /* + * The local APIC is being enabled. If the per-vCPU upcall vector is + * set and the vCPU's evtchn_upcall_pending flag is set, inject the + * interrupt. + */ + if (static_branch_unlikely(&kvm_xen_enabled.key) && + vcpu->arch.xen.vcpu_info_cache.active && + vcpu->arch.xen.upcall_vector && __kvm_xen_has_interrupt(vcpu)) + kvm_xen_inject_vcpu_vector(vcpu); +} + static inline bool kvm_xen_msr_enabled(struct kvm *kvm) { return static_branch_unlikely(&kvm_xen_enabled.key) && @@ -101,6 +115,10 @@ { } +static inline void kvm_xen_sw_enable_lapic(struct kvm_vcpu *vcpu) +{ +} + static inline bool kvm_xen_msr_enabled(struct kvm *kvm) { return false; --- linux-xilinx-6.8.0.orig/arch/x86/lib/Makefile +++ linux-xilinx-6.8.0/arch/x86/lib/Makefile @@ -14,19 +14,6 @@ CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE) endif -# Early boot use of cmdline; don't instrument it -ifdef CONFIG_AMD_MEM_ENCRYPT -KCOV_INSTRUMENT_cmdline.o := n -KASAN_SANITIZE_cmdline.o := n -KCSAN_SANITIZE_cmdline.o := n - -ifdef CONFIG_FUNCTION_TRACER -CFLAGS_REMOVE_cmdline.o = -pg -endif - -CFLAGS_cmdline.o := -fno-stack-protector -fno-jump-tables -endif - inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt quiet_cmd_inat_tables = GEN $@ --- linux-xilinx-6.8.0.orig/arch/x86/lib/getuser.S +++ linux-xilinx-6.8.0/arch/x86/lib/getuser.S @@ -44,7 +44,11 @@ or %rdx, %rax .else cmp $TASK_SIZE_MAX-\size+1, %eax +.if \size != 8 jae .Lbad_get_user +.else + jae .Lbad_get_user_8 +.endif sbb %edx, %edx /* array_index_mask_nospec() */ and %edx, %eax .endif @@ -154,7 +158,7 @@ #ifdef CONFIG_X86_32 SYM_CODE_START_LOCAL(__get_user_8_handle_exception) ASM_CLAC -bad_get_user_8: +.Lbad_get_user_8: xor %edx,%edx xor %ecx,%ecx mov $(-EFAULT),%_ASM_AX --- linux-xilinx-6.8.0.orig/arch/x86/lib/retpoline.S +++ linux-xilinx-6.8.0/arch/x86/lib/retpoline.S @@ -163,6 +163,7 @@ lfence jmp srso_alias_return_thunk SYM_FUNC_END(srso_alias_untrain_ret) +__EXPORT_THUNK(srso_alias_untrain_ret) .popsection .pushsection .text..__x86.rethunk_safe @@ -224,10 +225,16 @@ SYM_CODE_END(srso_return_thunk) #define JMP_SRSO_UNTRAIN_RET "jmp srso_untrain_ret" -#define JMP_SRSO_ALIAS_UNTRAIN_RET "jmp srso_alias_untrain_ret" #else /* !CONFIG_CPU_SRSO */ #define JMP_SRSO_UNTRAIN_RET "ud2" -#define JMP_SRSO_ALIAS_UNTRAIN_RET "ud2" +/* Dummy for the alternative in CALL_UNTRAIN_RET. */ +SYM_CODE_START(srso_alias_untrain_ret) + ANNOTATE_UNRET_SAFE + ANNOTATE_NOENDBR + ret + int3 +SYM_FUNC_END(srso_alias_untrain_ret) +__EXPORT_THUNK(srso_alias_untrain_ret) #endif /* CONFIG_CPU_SRSO */ #ifdef CONFIG_CPU_UNRET_ENTRY @@ -319,9 +326,7 @@ #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO) SYM_FUNC_START(entry_untrain_ret) - ALTERNATIVE_2 JMP_RETBLEED_UNTRAIN_RET, \ - JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO, \ - JMP_SRSO_ALIAS_UNTRAIN_RET, X86_FEATURE_SRSO_ALIAS + ALTERNATIVE JMP_RETBLEED_UNTRAIN_RET, JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO SYM_FUNC_END(entry_untrain_ret) __EXPORT_THUNK(entry_untrain_ret) --- linux-xilinx-6.8.0.orig/arch/x86/lib/x86-opcode-map.txt +++ linux-xilinx-6.8.0/arch/x86/lib/x86-opcode-map.txt @@ -148,7 +148,7 @@ 65: SEG=GS (Prefix) 66: Operand-Size (Prefix) 67: Address-Size (Prefix) -68: PUSH Iz (d64) +68: PUSH Iz 69: IMUL Gv,Ev,Iz 6a: PUSH Ib (d64) 6b: IMUL Gv,Ev,Ib @@ -698,10 +698,10 @@ 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev) 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev) 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev) -50: vpdpbusd Vx,Hx,Wx (66),(ev) -51: vpdpbusds Vx,Hx,Wx (66),(ev) -52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) -53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) +50: vpdpbusd Vx,Hx,Wx (66) +51: vpdpbusds Vx,Hx,Wx (66) +52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev) +53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev) 54: vpopcntb/w Vx,Wx (66),(ev) 55: vpopcntd/q Vx,Wx (66),(ev) 58: vpbroadcastd Vx,Wx (66),(v) --- linux-xilinx-6.8.0.orig/arch/x86/mm/fault.c +++ linux-xilinx-6.8.0/arch/x86/mm/fault.c @@ -376,7 +376,7 @@ goto bad; pr_cont("PUD %lx ", pud_val(*pud)); - if (!pud_present(*pud) || pud_large(*pud)) + if (!pud_present(*pud) || pud_leaf(*pud)) goto out; pmd = pmd_offset(pud, address); @@ -717,39 +717,8 @@ WARN_ON_ONCE(user_mode(regs)); /* Are we prepared to handle this kernel fault? */ - if (fixup_exception(regs, X86_TRAP_PF, error_code, address)) { - /* - * Any interrupt that takes a fault gets the fixup. This makes - * the below recursive fault logic only apply to a faults from - * task context. - */ - if (in_interrupt()) - return; - - /* - * Per the above we're !in_interrupt(), aka. task context. - * - * In this case we need to make sure we're not recursively - * faulting through the emulate_vsyscall() logic. - */ - if (current->thread.sig_on_uaccess_err && signal) { - sanitize_error_code(address, &error_code); - - set_signal_archinfo(address, error_code); - - if (si_code == SEGV_PKUERR) { - force_sig_pkuerr((void __user *)address, pkey); - } else { - /* XXX: hwpoison faults will set the wrong code. */ - force_sig_fault(signal, si_code, (void __user *)address); - } - } - - /* - * Barring that, we can do the fixup and be happy. - */ + if (fixup_exception(regs, X86_TRAP_PF, error_code, address)) return; - } /* * AMD erratum #91 manifests as a spurious page fault on a PREFETCH @@ -1037,7 +1006,7 @@ if (!pud_present(*pud)) return 0; - if (pud_large(*pud)) + if (pud_leaf(*pud)) return spurious_kernel_fault_check(error_code, (pte_t *) pud); pmd = pmd_offset(pud, address); --- linux-xilinx-6.8.0.orig/arch/x86/mm/ident_map.c +++ linux-xilinx-6.8.0/arch/x86/mm/ident_map.c @@ -26,31 +26,18 @@ for (; addr < end; addr = next) { pud_t *pud = pud_page + pud_index(addr); pmd_t *pmd; - bool use_gbpage; next = (addr & PUD_MASK) + PUD_SIZE; if (next > end) next = end; - /* if this is already a gbpage, this portion is already mapped */ - if (pud_large(*pud)) - continue; - - /* Is using a gbpage allowed? */ - use_gbpage = info->direct_gbpages; - - /* Don't use gbpage if it maps more than the requested region. */ - /* at the begining: */ - use_gbpage &= ((addr & ~PUD_MASK) == 0); - /* ... or at the end: */ - use_gbpage &= ((next & ~PUD_MASK) == 0); - - /* Never overwrite existing mappings */ - use_gbpage &= !pud_present(*pud); - - if (use_gbpage) { + if (info->direct_gbpages) { pud_t pudval; + if (pud_present(*pud)) + continue; + + addr &= PUD_MASK; pudval = __pud((addr - info->offset) | info->page_flag); set_pud(pud, pudval); continue; --- linux-xilinx-6.8.0.orig/arch/x86/mm/init_64.c +++ linux-xilinx-6.8.0/arch/x86/mm/init_64.c @@ -617,7 +617,7 @@ } if (!pud_none(*pud)) { - if (!pud_large(*pud)) { + if (!pud_leaf(*pud)) { pmd = pmd_offset(pud, 0); paddr_last = phys_pmd_init(pmd, paddr, paddr_end, @@ -1163,7 +1163,7 @@ if (!pud_present(*pud)) continue; - if (pud_large(*pud) && + if (pud_leaf(*pud) && IS_ALIGNED(addr, PUD_SIZE) && IS_ALIGNED(next, PUD_SIZE)) { spin_lock(&init_mm.page_table_lock); --- linux-xilinx-6.8.0.orig/arch/x86/mm/kasan_init_64.c +++ linux-xilinx-6.8.0/arch/x86/mm/kasan_init_64.c @@ -115,7 +115,7 @@ pud = pud_offset(p4d, addr); do { next = pud_addr_end(addr, end); - if (!pud_large(*pud)) + if (!pud_leaf(*pud)) kasan_populate_pud(pud, addr, next, nid); } while (pud++, addr = next, addr != end); } --- linux-xilinx-6.8.0.orig/arch/x86/mm/mem_encrypt_amd.c +++ linux-xilinx-6.8.0/arch/x86/mm/mem_encrypt_amd.c @@ -492,6 +492,24 @@ */ if (sev_status & MSR_AMD64_SEV_ENABLED) ia32_disable(); + + /* + * Override init functions that scan the ROM region in SEV-SNP guests, + * as this memory is not pre-validated and would thus cause a crash. + */ + if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) { + x86_init.mpparse.find_smp_config = x86_init_noop; + x86_init.pci.init_irq = x86_init_noop; + x86_init.resources.probe_roms = x86_init_noop; + + /* + * DMI setup behavior for SEV-SNP guests depends on + * efi_enabled(EFI_CONFIG_TABLES), which hasn't been + * parsed yet. snp_dmi_setup() will run after that + * parsing has happened. + */ + x86_init.resources.dmi_setup = snp_dmi_setup; + } } void __init mem_encrypt_free_decrypted_mem(void) --- linux-xilinx-6.8.0.orig/arch/x86/mm/mem_encrypt_identity.c +++ linux-xilinx-6.8.0/arch/x86/mm/mem_encrypt_identity.c @@ -41,9 +41,9 @@ #include #include +#include #include #include -#include #include #include @@ -95,11 +95,7 @@ */ static char sme_workarea[2 * PMD_SIZE] __section(".init.scratch"); -static char sme_cmdline_arg[] __initdata = "mem_encrypt"; -static char sme_cmdline_on[] __initdata = "on"; -static char sme_cmdline_off[] __initdata = "off"; - -static void __init sme_clear_pgd(struct sme_populate_pgd_data *ppd) +static void __head sme_clear_pgd(struct sme_populate_pgd_data *ppd) { unsigned long pgd_start, pgd_end, pgd_size; pgd_t *pgd_p; @@ -114,7 +110,7 @@ memset(pgd_p, 0, pgd_size); } -static pud_t __init *sme_prepare_pgd(struct sme_populate_pgd_data *ppd) +static pud_t __head *sme_prepare_pgd(struct sme_populate_pgd_data *ppd) { pgd_t *pgd; p4d_t *p4d; @@ -145,13 +141,13 @@ set_pud(pud, __pud(PUD_FLAGS | __pa(pmd))); } - if (pud_large(*pud)) + if (pud_leaf(*pud)) return NULL; return pud; } -static void __init sme_populate_pgd_large(struct sme_populate_pgd_data *ppd) +static void __head sme_populate_pgd_large(struct sme_populate_pgd_data *ppd) { pud_t *pud; pmd_t *pmd; @@ -167,7 +163,7 @@ set_pmd(pmd, __pmd(ppd->paddr | ppd->pmd_flags)); } -static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd) +static void __head sme_populate_pgd(struct sme_populate_pgd_data *ppd) { pud_t *pud; pmd_t *pmd; @@ -193,7 +189,7 @@ set_pte(pte, __pte(ppd->paddr | ppd->pte_flags)); } -static void __init __sme_map_range_pmd(struct sme_populate_pgd_data *ppd) +static void __head __sme_map_range_pmd(struct sme_populate_pgd_data *ppd) { while (ppd->vaddr < ppd->vaddr_end) { sme_populate_pgd_large(ppd); @@ -203,7 +199,7 @@ } } -static void __init __sme_map_range_pte(struct sme_populate_pgd_data *ppd) +static void __head __sme_map_range_pte(struct sme_populate_pgd_data *ppd) { while (ppd->vaddr < ppd->vaddr_end) { sme_populate_pgd(ppd); @@ -213,7 +209,7 @@ } } -static void __init __sme_map_range(struct sme_populate_pgd_data *ppd, +static void __head __sme_map_range(struct sme_populate_pgd_data *ppd, pmdval_t pmd_flags, pteval_t pte_flags) { unsigned long vaddr_end; @@ -237,22 +233,22 @@ __sme_map_range_pte(ppd); } -static void __init sme_map_range_encrypted(struct sme_populate_pgd_data *ppd) +static void __head sme_map_range_encrypted(struct sme_populate_pgd_data *ppd) { __sme_map_range(ppd, PMD_FLAGS_ENC, PTE_FLAGS_ENC); } -static void __init sme_map_range_decrypted(struct sme_populate_pgd_data *ppd) +static void __head sme_map_range_decrypted(struct sme_populate_pgd_data *ppd) { __sme_map_range(ppd, PMD_FLAGS_DEC, PTE_FLAGS_DEC); } -static void __init sme_map_range_decrypted_wp(struct sme_populate_pgd_data *ppd) +static void __head sme_map_range_decrypted_wp(struct sme_populate_pgd_data *ppd) { __sme_map_range(ppd, PMD_FLAGS_DEC_WP, PTE_FLAGS_DEC_WP); } -static unsigned long __init sme_pgtable_calc(unsigned long len) +static unsigned long __head sme_pgtable_calc(unsigned long len) { unsigned long entries = 0, tables = 0; @@ -289,7 +285,7 @@ return entries + tables; } -void __init sme_encrypt_kernel(struct boot_params *bp) +void __head sme_encrypt_kernel(struct boot_params *bp) { unsigned long workarea_start, workarea_end, workarea_len; unsigned long execute_start, execute_end, execute_len; @@ -305,7 +301,8 @@ * instrumentation or checking boot_cpu_data in the cc_platform_has() * function. */ - if (!sme_get_me_mask() || sev_status & MSR_AMD64_SEV_ENABLED) + if (!sme_get_me_mask() || + RIP_REL_REF(sev_status) & MSR_AMD64_SEV_ENABLED) return; /* @@ -323,9 +320,8 @@ * memory from being cached. */ - /* Physical addresses gives us the identity mapped virtual addresses */ - kernel_start = __pa_symbol(_text); - kernel_end = ALIGN(__pa_symbol(_end), PMD_SIZE); + kernel_start = (unsigned long)RIP_REL_REF(_text); + kernel_end = ALIGN((unsigned long)RIP_REL_REF(_end), PMD_SIZE); kernel_len = kernel_end - kernel_start; initrd_start = 0; @@ -343,14 +339,6 @@ #endif /* - * We're running identity mapped, so we must obtain the address to the - * SME encryption workarea using rip-relative addressing. - */ - asm ("lea sme_workarea(%%rip), %0" - : "=r" (workarea_start) - : "p" (sme_workarea)); - - /* * Calculate required number of workarea bytes needed: * executable encryption area size: * stack page (PAGE_SIZE) @@ -359,7 +347,7 @@ * pagetable structures for the encryption of the kernel * pagetable structures for workarea (in case not currently mapped) */ - execute_start = workarea_start; + execute_start = workarea_start = (unsigned long)RIP_REL_REF(sme_workarea); execute_end = execute_start + (PAGE_SIZE * 2) + PMD_SIZE; execute_len = execute_end - execute_start; @@ -502,14 +490,11 @@ native_write_cr3(__native_read_cr3()); } -void __init sme_enable(struct boot_params *bp) +void __head sme_enable(struct boot_params *bp) { - const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off; unsigned int eax, ebx, ecx, edx; unsigned long feature_mask; - bool active_by_default; unsigned long me_mask; - char buffer[16]; bool snp; u64 msr; @@ -543,15 +528,18 @@ me_mask = 1UL << (ebx & 0x3f); /* Check the SEV MSR whether SEV or SME is enabled */ - sev_status = __rdmsr(MSR_AMD64_SEV); - feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT; + RIP_REL_REF(sev_status) = msr = __rdmsr(MSR_AMD64_SEV); + feature_mask = (msr & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT; /* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */ - if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED)) + if (snp && !(msr & MSR_AMD64_SEV_SNP_ENABLED)) snp_abort(); /* Check if memory encryption is enabled */ if (feature_mask == AMD_SME_BIT) { + if (!(bp->hdr.xloadflags & XLF_MEM_ENCRYPTION)) + return; + /* * No SME if Hypervisor bit is set. This check is here to * prevent a guest from trying to enable SME. For running as a @@ -571,48 +559,10 @@ msr = __rdmsr(MSR_AMD64_SYSCFG); if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT)) return; - } else { - /* SEV state cannot be controlled by a command line option */ - sme_me_mask = me_mask; - goto out; } - /* - * Fixups have not been applied to phys_base yet and we're running - * identity mapped, so we must obtain the address to the SME command - * line argument data using rip-relative addressing. - */ - asm ("lea sme_cmdline_arg(%%rip), %0" - : "=r" (cmdline_arg) - : "p" (sme_cmdline_arg)); - asm ("lea sme_cmdline_on(%%rip), %0" - : "=r" (cmdline_on) - : "p" (sme_cmdline_on)); - asm ("lea sme_cmdline_off(%%rip), %0" - : "=r" (cmdline_off) - : "p" (sme_cmdline_off)); - - if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT)) - active_by_default = true; - else - active_by_default = false; - - cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr | - ((u64)bp->ext_cmd_line_ptr << 32)); - - if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0) - return; - - if (!strncmp(buffer, cmdline_on, sizeof(buffer))) - sme_me_mask = me_mask; - else if (!strncmp(buffer, cmdline_off, sizeof(buffer))) - sme_me_mask = 0; - else - sme_me_mask = active_by_default ? me_mask : 0; -out: - if (sme_me_mask) { - physical_mask &= ~sme_me_mask; - cc_vendor = CC_VENDOR_AMD; - cc_set_mask(sme_me_mask); - } + RIP_REL_REF(sme_me_mask) = me_mask; + physical_mask &= ~me_mask; + cc_vendor = CC_VENDOR_AMD; + cc_set_mask(me_mask); } --- linux-xilinx-6.8.0.orig/arch/x86/mm/numa.c +++ linux-xilinx-6.8.0/arch/x86/mm/numa.c @@ -493,7 +493,7 @@ for_each_reserved_mem_region(mb_region) { int nid = memblock_get_region_node(mb_region); - if (nid != MAX_NUMNODES) + if (nid != NUMA_NO_NODE) node_set(nid, reserved_nodemask); } @@ -614,9 +614,9 @@ nodes_clear(node_online_map); memset(&numa_meminfo, 0, sizeof(numa_meminfo)); WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory, - MAX_NUMNODES)); + NUMA_NO_NODE)); WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved, - MAX_NUMNODES)); + NUMA_NO_NODE)); /* In case that parsing SRAT failed. */ WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX)); numa_reset_distance(); @@ -929,6 +929,8 @@ } EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); +#endif + static int __init cmp_memblk(const void *a, const void *b) { const struct numa_memblk *ma = *(const struct numa_memblk **)a; @@ -1001,5 +1003,3 @@ } return 0; } - -#endif --- linux-xilinx-6.8.0.orig/arch/x86/mm/pat/memtype.c +++ linux-xilinx-6.8.0/arch/x86/mm/pat/memtype.c @@ -950,6 +950,38 @@ memtype_free(paddr, paddr + size); } +static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr, + pgprot_t *pgprot) +{ + unsigned long prot; + + VM_WARN_ON_ONCE(!(vma->vm_flags & VM_PAT)); + + /* + * We need the starting PFN and cachemode used for track_pfn_remap() + * that covered the whole VMA. For most mappings, we can obtain that + * information from the page tables. For COW mappings, we might now + * suddenly have anon folios mapped and follow_phys() will fail. + * + * Fallback to using vma->vm_pgoff, see remap_pfn_range_notrack(), to + * detect the PFN. If we need the cachemode as well, we're out of luck + * for now and have to fail fork(). + */ + if (!follow_phys(vma, vma->vm_start, 0, &prot, paddr)) { + if (pgprot) + *pgprot = __pgprot(prot); + return 0; + } + if (is_cow_mapping(vma->vm_flags)) { + if (pgprot) + return -EINVAL; + *paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT; + return 0; + } + WARN_ON_ONCE(1); + return -EINVAL; +} + /* * track_pfn_copy is called when vma that is covering the pfnmap gets * copied through copy_page_range(). @@ -960,20 +992,13 @@ int track_pfn_copy(struct vm_area_struct *vma) { resource_size_t paddr; - unsigned long prot; unsigned long vma_size = vma->vm_end - vma->vm_start; pgprot_t pgprot; if (vma->vm_flags & VM_PAT) { - /* - * reserve the whole chunk covered by vma. We need the - * starting address and protection from pte. - */ - if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) { - WARN_ON_ONCE(1); + if (get_pat_info(vma, &paddr, &pgprot)) return -EINVAL; - } - pgprot = __pgprot(prot); + /* reserve the whole chunk covered by vma. */ return reserve_pfn_range(paddr, vma_size, &pgprot, 1); } @@ -1048,7 +1073,6 @@ unsigned long size, bool mm_wr_locked) { resource_size_t paddr; - unsigned long prot; if (vma && !(vma->vm_flags & VM_PAT)) return; @@ -1056,11 +1080,8 @@ /* free the chunk starting from pfn or the whole chunk */ paddr = (resource_size_t)pfn << PAGE_SHIFT; if (!paddr && !size) { - if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) { - WARN_ON_ONCE(1); + if (get_pat_info(vma, &paddr, NULL)) return; - } - size = vma->vm_end - vma->vm_start; } free_pfn_range(paddr, size); --- linux-xilinx-6.8.0.orig/arch/x86/mm/pat/set_memory.c +++ linux-xilinx-6.8.0/arch/x86/mm/pat/set_memory.c @@ -619,7 +619,8 @@ * Validate strict W^X semantics. */ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long start, - unsigned long pfn, unsigned long npg) + unsigned long pfn, unsigned long npg, + bool nx, bool rw) { unsigned long end; @@ -641,6 +642,10 @@ if ((pgprot_val(new) & (_PAGE_RW | _PAGE_NX)) != _PAGE_RW) return new; + /* Non-leaf translation entries can disable writing or execution. */ + if (!rw || nx) + return new; + end = start + npg * PAGE_SIZE - 1; WARN_ONCE(1, "CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n", (unsigned long long)pgprot_val(old), @@ -657,20 +662,26 @@ /* * Lookup the page table entry for a virtual address in a specific pgd. - * Return a pointer to the entry and the level of the mapping. + * Return a pointer to the entry, the level of the mapping, and the effective + * NX and RW bits of all page table levels. */ -pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, - unsigned int *level) +pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address, + unsigned int *level, bool *nx, bool *rw) { p4d_t *p4d; pud_t *pud; pmd_t *pmd; *level = PG_LEVEL_NONE; + *nx = false; + *rw = true; if (pgd_none(*pgd)) return NULL; + *nx |= pgd_flags(*pgd) & _PAGE_NX; + *rw &= pgd_flags(*pgd) & _PAGE_RW; + p4d = p4d_offset(pgd, address); if (p4d_none(*p4d)) return NULL; @@ -679,14 +690,20 @@ if (p4d_large(*p4d) || !p4d_present(*p4d)) return (pte_t *)p4d; + *nx |= p4d_flags(*p4d) & _PAGE_NX; + *rw &= p4d_flags(*p4d) & _PAGE_RW; + pud = pud_offset(p4d, address); if (pud_none(*pud)) return NULL; *level = PG_LEVEL_1G; - if (pud_large(*pud) || !pud_present(*pud)) + if (pud_leaf(*pud) || !pud_present(*pud)) return (pte_t *)pud; + *nx |= pud_flags(*pud) & _PAGE_NX; + *rw &= pud_flags(*pud) & _PAGE_RW; + pmd = pmd_offset(pud, address); if (pmd_none(*pmd)) return NULL; @@ -695,12 +712,27 @@ if (pmd_large(*pmd) || !pmd_present(*pmd)) return (pte_t *)pmd; + *nx |= pmd_flags(*pmd) & _PAGE_NX; + *rw &= pmd_flags(*pmd) & _PAGE_RW; + *level = PG_LEVEL_4K; return pte_offset_kernel(pmd, address); } /* + * Lookup the page table entry for a virtual address in a specific pgd. + * Return a pointer to the entry and the level of the mapping. + */ +pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, + unsigned int *level) +{ + bool nx, rw; + + return lookup_address_in_pgd_attr(pgd, address, level, &nx, &rw); +} + +/* * Lookup the page table entry for a virtual address. Return a pointer * to the entry and the level of the mapping. * @@ -715,13 +747,16 @@ EXPORT_SYMBOL_GPL(lookup_address); static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address, - unsigned int *level) + unsigned int *level, bool *nx, bool *rw) { - if (cpa->pgd) - return lookup_address_in_pgd(cpa->pgd + pgd_index(address), - address, level); + pgd_t *pgd; + + if (!cpa->pgd) + pgd = pgd_offset_k(address); + else + pgd = cpa->pgd + pgd_index(address); - return lookup_address(address, level); + return lookup_address_in_pgd_attr(pgd, address, level, nx, rw); } /* @@ -743,7 +778,7 @@ return NULL; pud = pud_offset(p4d, address); - if (pud_none(*pud) || pud_large(*pud) || !pud_present(*pud)) + if (pud_none(*pud) || pud_leaf(*pud) || !pud_present(*pud)) return NULL; return pmd_offset(pud, address); @@ -849,12 +884,13 @@ pgprot_t old_prot, new_prot, req_prot, chk_prot; pte_t new_pte, *tmp; enum pg_level level; + bool nx, rw; /* * Check for races, another CPU might have split this page * up already: */ - tmp = _lookup_address_cpa(cpa, address, &level); + tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw); if (tmp != kpte) return 1; @@ -965,7 +1001,8 @@ new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages, psize, CPA_DETECT); - new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages); + new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages, + nx, rw); /* * If there is a conflict, split the large page. @@ -1046,6 +1083,7 @@ pte_t *pbase = (pte_t *)page_address(base); unsigned int i, level; pgprot_t ref_prot; + bool nx, rw; pte_t *tmp; spin_lock(&pgd_lock); @@ -1053,7 +1091,7 @@ * Check for races, another CPU might have split this page * up for us already: */ - tmp = _lookup_address_cpa(cpa, address, &level); + tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw); if (tmp != kpte) { spin_unlock(&pgd_lock); return 1; @@ -1278,7 +1316,7 @@ */ while (end - start >= PUD_SIZE) { - if (pud_large(*pud)) + if (pud_leaf(*pud)) pud_clear(pud); else unmap_pmd_range(pud, start, start + PUD_SIZE); @@ -1594,10 +1632,11 @@ int do_split, err; unsigned int level; pte_t *kpte, old_pte; + bool nx, rw; address = __cpa_addr(cpa, cpa->curpage); repeat: - kpte = _lookup_address_cpa(cpa, address, &level); + kpte = _lookup_address_cpa(cpa, address, &level, &nx, &rw); if (!kpte) return __cpa_process_fault(cpa, address, primary); @@ -1619,7 +1658,8 @@ new_prot = static_protections(new_prot, address, pfn, 1, 0, CPA_PROTECT); - new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1); + new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1, + nx, rw); new_prot = pgprot_clear_protnone_bits(new_prot); --- linux-xilinx-6.8.0.orig/arch/x86/mm/pgtable.c +++ linux-xilinx-6.8.0/arch/x86/mm/pgtable.c @@ -631,6 +631,8 @@ pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp) { + VM_WARN_ON_ONCE(!pmd_present(*pmdp)); + /* * No flush is necessary. Once an invalid PTE is established, the PTE's * access and dirty bits cannot be updated. @@ -777,7 +779,7 @@ */ int pud_clear_huge(pud_t *pud) { - if (pud_large(*pud)) { + if (pud_leaf(*pud)) { pud_clear(pud); return 1; } --- linux-xilinx-6.8.0.orig/arch/x86/mm/pti.c +++ linux-xilinx-6.8.0/arch/x86/mm/pti.c @@ -217,7 +217,7 @@ pud = pud_offset(p4d, address); /* The user page tables do not use large mappings: */ - if (pud_large(*pud)) { + if (pud_leaf(*pud)) { WARN_ON(1); return NULL; } --- linux-xilinx-6.8.0.orig/arch/x86/net/bpf_jit_comp.c +++ linux-xilinx-6.8.0/arch/x86/net/bpf_jit_comp.c @@ -466,7 +466,7 @@ static int emit_rsb_call(u8 **pprog, void *func, void *ip) { OPTIMIZER_HIDE_VAR(func); - x86_call_depth_emit_accounting(pprog, func); + ip += x86_call_depth_emit_accounting(pprog, func); return emit_patch(pprog, func, ip, 0xE8); } @@ -1585,36 +1585,41 @@ if (BPF_MODE(insn->code) == BPF_PROBE_MEM || BPF_MODE(insn->code) == BPF_PROBE_MEMSX) { /* Conservatively check that src_reg + insn->off is a kernel address: - * src_reg + insn->off >= TASK_SIZE_MAX + PAGE_SIZE - * src_reg is used as scratch for src_reg += insn->off and restored - * after emit_ldx if necessary + * src_reg + insn->off > TASK_SIZE_MAX + PAGE_SIZE + * and + * src_reg + insn->off < VSYSCALL_ADDR */ - u64 limit = TASK_SIZE_MAX + PAGE_SIZE; + u64 limit = TASK_SIZE_MAX + PAGE_SIZE - VSYSCALL_ADDR; u8 *end_of_jmp; - /* At end of these emitted checks, insn->off will have been added - * to src_reg, so no need to do relative load with insn->off offset - */ - insn_off = 0; + /* movabsq r10, VSYSCALL_ADDR */ + emit_mov_imm64(&prog, BPF_REG_AX, (long)VSYSCALL_ADDR >> 32, + (u32)(long)VSYSCALL_ADDR); - /* movabsq r11, limit */ - EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG)); - EMIT((u32)limit, 4); - EMIT(limit >> 32, 4); + /* mov src_reg, r11 */ + EMIT_mov(AUX_REG, src_reg); if (insn->off) { - /* add src_reg, insn->off */ - maybe_emit_1mod(&prog, src_reg, true); - EMIT2_off32(0x81, add_1reg(0xC0, src_reg), insn->off); + /* add r11, insn->off */ + maybe_emit_1mod(&prog, AUX_REG, true); + EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off); } - /* cmp src_reg, r11 */ - maybe_emit_mod(&prog, src_reg, AUX_REG, true); - EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG)); + /* sub r11, r10 */ + maybe_emit_mod(&prog, AUX_REG, BPF_REG_AX, true); + EMIT2(0x29, add_2reg(0xC0, AUX_REG, BPF_REG_AX)); + + /* movabsq r10, limit */ + emit_mov_imm64(&prog, BPF_REG_AX, (long)limit >> 32, + (u32)(long)limit); + + /* cmp r10, r11 */ + maybe_emit_mod(&prog, AUX_REG, BPF_REG_AX, true); + EMIT2(0x39, add_2reg(0xC0, AUX_REG, BPF_REG_AX)); - /* if unsigned '>=', goto load */ - EMIT2(X86_JAE, 0); + /* if unsigned '>', goto load */ + EMIT2(X86_JA, 0); end_of_jmp = prog; /* xor dst_reg, dst_reg */ @@ -1640,18 +1645,6 @@ /* populate jmp_offset for JMP above */ start_of_ldx[-1] = prog - start_of_ldx; - if (insn->off && src_reg != dst_reg) { - /* sub src_reg, insn->off - * Restore src_reg after "add src_reg, insn->off" in prev - * if statement. But if src_reg == dst_reg, emit_ldx - * above already clobbered src_reg, so no need to restore. - * If add src_reg, insn->off was unnecessary, no need to - * restore either. - */ - maybe_emit_1mod(&prog, src_reg, true); - EMIT2_off32(0x81, add_1reg(0xE8, src_reg), insn->off); - } - if (!bpf_prog->aux->extable) break; --- linux-xilinx-6.8.0.orig/arch/x86/net/bpf_jit_comp32.c +++ linux-xilinx-6.8.0/arch/x86/net/bpf_jit_comp32.c @@ -2600,8 +2600,7 @@ if (bpf_jit_enable > 1) bpf_jit_dump(prog->len, proglen, pass + 1, image); - if (image) { - bpf_jit_binary_lock_ro(header); + if (image && !bpf_jit_binary_lock_ro(header)) { prog->bpf_func = (void *)image; prog->jited = 1; prog->jited_len = proglen; --- linux-xilinx-6.8.0.orig/arch/x86/pci/common.c +++ linux-xilinx-6.8.0/arch/x86/pci/common.c @@ -34,6 +34,7 @@ #endif int pcibios_last_bus = -1; unsigned long pirq_table_addr; +unsigned int pci_early_clear_msi; const struct pci_raw_ops *__read_mostly raw_pci_ops; const struct pci_raw_ops *__read_mostly raw_pci_ext_ops; @@ -614,6 +615,9 @@ } else if (!strcmp(str, "skip_isa_align")) { pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; return NULL; + } else if (!strcmp(str, "clearmsi")) { + pci_early_clear_msi = 1; + return NULL; } else if (!strcmp(str, "noioapicquirk")) { noioapicquirk = 1; return NULL; --- linux-xilinx-6.8.0.orig/arch/x86/pci/early.c +++ linux-xilinx-6.8.0/arch/x86/pci/early.c @@ -51,6 +51,31 @@ outw(val, 0xcfc + (offset&2)); } +u32 pci_early_find_cap(int bus, int slot, int func, int cap) +{ + int bytes; + u8 pos; + + if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) & + PCI_STATUS_CAP_LIST)) + return 0; + + pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST); + for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { + u8 id; + + pos &= ~3; + id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID); + if (id == 0xff) + break; + if (id == cap) + return pos; + pos = read_pci_config_byte(bus, slot, func, + pos+PCI_CAP_LIST_NEXT); + } + return 0; +} + int early_pci_allowed(void) { return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == --- linux-xilinx-6.8.0.orig/arch/x86/pci/fixup.c +++ linux-xilinx-6.8.0/arch/x86/pci/fixup.c @@ -907,6 +907,54 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_save_apl_pci_l1ss_capability); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_fixup_apl_pci_l1ss_capability); +/* + * Disable D3cold on Asus B1400 PCI-NVMe bridge + * + * On this platform with VMD off, the NVMe device cannot successfully power + * back on from D3cold. This appears to be an untested transition by the + * vendor: Windows leaves the NVMe and parent bridge in D0 during suspend. + * + * We disable D3cold on the parent bridge for simplicity, and the fact that + * both parent bridge and NVMe device share the same power resource. + * + * This is only needed on BIOS versions before 308; the newer versions flip + * StorageD3Enable from 1 to 0. + */ +static const struct dmi_system_id asus_nvme_broken_d3cold_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.304"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.305"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.306"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.307"), + }, + }, + {} +}; + +static void asus_disable_nvme_d3cold(struct pci_dev *pdev) +{ + if (dmi_check_system(asus_nvme_broken_d3cold_table) > 0) + pci_d3cold_disable(pdev); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold); + #ifdef CONFIG_SUSPEND /* * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but --- linux-xilinx-6.8.0.orig/arch/x86/pci/mmconfig-shared.c +++ linux-xilinx-6.8.0/arch/x86/pci/mmconfig-shared.c @@ -518,7 +518,34 @@ { struct resource *conflict; - if (!early && !acpi_disabled) { + if (early) { + + /* + * Don't try to do this check unless configuration type 1 + * is available. How about type 2? + */ + + /* + * 946f2ee5c731 ("Check that MCFG points to an e820 + * reserved area") added this E820 check in 2006 to work + * around BIOS defects. + * + * Per PCI Firmware r3.3, sec 4.1.2, ECAM space must be + * reserved by a PNP0C02 resource, but it need not be + * mentioned in E820. Before the ACPI interpreter is + * available, we can't check for PNP0C02 resources, so + * there's no reliable way to verify the region in this + * early check. Keep it only for the old machines that + * motivated 946f2ee5c731. + */ + if (dmi_get_bios_year() < 2016 && raw_pci_ops) + return is_mmconf_reserved(e820__mapped_all, cfg, dev, + "E820 entry"); + + return true; + } + + if (!acpi_disabled) { if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, "ACPI motherboard resource")) return true; @@ -551,16 +578,7 @@ * For MCFG information constructed from hotpluggable host bridge's * _CBA method, just assume it's reserved. */ - if (pci_mmcfg_running_state) - return true; - - /* Don't try to do this check unless configuration - type 1 is available. how about type 2 ?*/ - if (raw_pci_ops) - return is_mmconf_reserved(e820__mapped_all, cfg, dev, - "E820 entry"); - - return false; + return pci_mmcfg_running_state; } static void __init pci_mmcfg_reject_broken(int early) --- linux-xilinx-6.8.0.orig/arch/x86/platform/efi/memmap.c +++ linux-xilinx-6.8.0/arch/x86/platform/efi/memmap.c @@ -92,12 +92,22 @@ */ int __init efi_memmap_install(struct efi_memory_map_data *data) { + unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map; + unsigned long flags = efi.memmap.flags; + u64 phys = efi.memmap.phys_map; + int ret; + efi_memmap_unmap(); if (efi_enabled(EFI_PARAVIRT)) return 0; - return __efi_memmap_init(data); + ret = __efi_memmap_init(data); + if (ret) + return ret; + + __efi_memmap_free(phys, size, flags); + return 0; } /** --- linux-xilinx-6.8.0.orig/arch/x86/platform/pvh/enlighten.c +++ linux-xilinx-6.8.0/arch/x86/platform/pvh/enlighten.c @@ -74,6 +74,9 @@ } else xen_raw_printk("Warning: Can fit ISA range into e820\n"); + if (xen_guest) + xen_reserve_extra_memory(&pvh_bootparams); + pvh_bootparams.hdr.cmd_line_ptr = pvh_start_info.cmdline_paddr; --- linux-xilinx-6.8.0.orig/arch/x86/power/hibernate.c +++ linux-xilinx-6.8.0/arch/x86/power/hibernate.c @@ -170,7 +170,7 @@ goto out; } pud = pud_offset(p4d, relocated_restore_code); - if (pud_large(*pud)) { + if (pud_leaf(*pud)) { set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX)); goto out; } --- linux-xilinx-6.8.0.orig/arch/x86/purgatory/Makefile +++ linux-xilinx-6.8.0/arch/x86/purgatory/Makefile @@ -42,7 +42,8 @@ # make up the standalone purgatory.ro PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel -PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0 +PURGATORY_CFLAGS := -mcmodel=small -ffreestanding -fno-zero-initialized-in-bss -g0 +PURGATORY_CFLAGS += -fpic -fvisibility=hidden PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING PURGATORY_CFLAGS += -fno-stack-protector --- linux-xilinx-6.8.0.orig/arch/x86/tools/relocs.c +++ linux-xilinx-6.8.0/arch/x86/tools/relocs.c @@ -653,6 +653,14 @@ if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { continue; } + /* + * Do not perform relocations in .notes section; any + * values there are meant for pre-boot consumption (e.g. + * startup_xen). + */ + if (sec_applies->shdr.sh_type == SHT_NOTE) { + continue; + } sh_symtab = sec_symtab->symtab; sym_strtab = sec_symtab->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { @@ -738,6 +746,15 @@ if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { continue; } + + /* + * Do not perform relocations in .notes sections; any + * values there are meant for pre-boot consumption (e.g. + * startup_xen). + */ + if (sec_applies->shdr.sh_type == SHT_NOTE) + continue; + sh_symtab = sec_symtab->symtab; sym_strtab = sec_symtab->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { --- linux-xilinx-6.8.0.orig/arch/x86/um/shared/sysdep/archsetjmp.h +++ linux-xilinx-6.8.0/arch/x86/um/shared/sysdep/archsetjmp.h @@ -1,6 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __X86_UM_SYSDEP_ARCHSETJMP_H +#define __X86_UM_SYSDEP_ARCHSETJMP_H + #ifdef __i386__ #include "archsetjmp_32.h" #else #include "archsetjmp_64.h" #endif + +unsigned long get_thread_reg(int reg, jmp_buf *buf); + +#endif /* __X86_UM_SYSDEP_ARCHSETJMP_H */ --- linux-xilinx-6.8.0.orig/arch/x86/xen/enlighten.c +++ linux-xilinx-6.8.0/arch/x86/xen/enlighten.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -350,3 +351,67 @@ } EXPORT_SYMBOL(xen_arch_unregister_cpu); #endif + +/* Amount of extra memory space we add to the e820 ranges */ +struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata; + +void __init xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns) +{ + unsigned int i; + + /* + * No need to check for zero size, should happen rarely and will only + * write a new entry regarded to be unused due to zero size. + */ + for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { + /* Add new region. */ + if (xen_extra_mem[i].n_pfns == 0) { + xen_extra_mem[i].start_pfn = start_pfn; + xen_extra_mem[i].n_pfns = n_pfns; + break; + } + /* Append to existing region. */ + if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns == + start_pfn) { + xen_extra_mem[i].n_pfns += n_pfns; + break; + } + } + if (i == XEN_EXTRA_MEM_MAX_REGIONS) + printk(KERN_WARNING "Warning: not enough extra memory regions\n"); + + memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns)); +} + +#ifdef CONFIG_XEN_UNPOPULATED_ALLOC +int __init arch_xen_unpopulated_init(struct resource **res) +{ + unsigned int i; + + if (!xen_domain()) + return -ENODEV; + + /* Must be set strictly before calling xen_free_unpopulated_pages(). */ + *res = &iomem_resource; + + /* + * Initialize with pages from the extra memory regions (see + * arch/x86/xen/setup.c). + */ + for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { + unsigned int j; + + for (j = 0; j < xen_extra_mem[i].n_pfns; j++) { + struct page *pg = + pfn_to_page(xen_extra_mem[i].start_pfn + j); + + xen_free_unpopulated_pages(1, &pg); + } + + /* Zero so region is not also added to the balloon driver. */ + xen_extra_mem[i].n_pfns = 0; + } + + return 0; +} +#endif --- linux-xilinx-6.8.0.orig/arch/x86/xen/enlighten_pvh.c +++ linux-xilinx-6.8.0/arch/x86/xen/enlighten_pvh.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include +#include #include @@ -72,3 +73,70 @@ } boot_params_p->e820_entries = memmap.nr_entries; } + +/* + * Reserve e820 UNUSABLE regions to inflate the memory balloon. + * + * On PVH dom0 the host memory map is used, RAM regions available to dom0 are + * located as the same place as in the native memory map, but since dom0 gets + * less memory than the total amount of host RAM the ranges that can't be + * populated are converted from RAM -> UNUSABLE. Use such regions (up to the + * ratio signaled in EXTRA_MEM_RATIO) in order to inflate the balloon driver at + * boot. Doing so prevents the guest (even if just temporary) from using holes + * in the memory map in order to map grants or foreign addresses, and + * hopefully limits the risk of a clash with a device MMIO region. Ideally the + * hypervisor should notify us which memory ranges are suitable for creating + * foreign mappings, but that's not yet implemented. + */ +void __init xen_reserve_extra_memory(struct boot_params *bootp) +{ + unsigned int i, ram_pages = 0, extra_pages; + + for (i = 0; i < bootp->e820_entries; i++) { + struct boot_e820_entry *e = &bootp->e820_table[i]; + + if (e->type != E820_TYPE_RAM) + continue; + ram_pages += PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr); + } + + /* Max amount of extra memory. */ + extra_pages = EXTRA_MEM_RATIO * ram_pages; + + /* + * Convert UNUSABLE ranges to RAM and reserve them for foreign mapping + * purposes. + */ + for (i = 0; i < bootp->e820_entries && extra_pages; i++) { + struct boot_e820_entry *e = &bootp->e820_table[i]; + unsigned long pages; + + if (e->type != E820_TYPE_UNUSABLE) + continue; + + pages = min(extra_pages, + PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr)); + + if (pages != (PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr))) { + struct boot_e820_entry *next; + + if (bootp->e820_entries == + ARRAY_SIZE(bootp->e820_table)) + /* No space left to split - skip region. */ + continue; + + /* Split entry. */ + next = e + 1; + memmove(next, e, + (bootp->e820_entries - i) * sizeof(*e)); + bootp->e820_entries++; + next->addr = PAGE_ALIGN(e->addr) + PFN_PHYS(pages); + e->size = next->addr - e->addr; + next->size -= e->size; + } + e->type = E820_TYPE_RAM; + extra_pages -= pages; + + xen_add_extra_mem(PFN_UP(e->addr), pages); + } +} --- linux-xilinx-6.8.0.orig/arch/x86/xen/mmu_pv.c +++ linux-xilinx-6.8.0/arch/x86/xen/mmu_pv.c @@ -1082,7 +1082,7 @@ pmd_t *pmd_tbl; int i; - if (pud_large(*pud)) { + if (pud_leaf(*pud)) { pa = pud_val(*pud) & PHYSICAL_PAGE_MASK; xen_free_ro_pages(pa, PUD_SIZE); return; @@ -1863,7 +1863,7 @@ if (!pud_present(pud)) return 0; pa = pud_val(pud) & PTE_PFN_MASK; - if (pud_large(pud)) + if (pud_leaf(pud)) return pa + (vaddr & ~PUD_MASK); pmd = native_make_pmd(xen_read_phys_ulong(pa + pmd_index(vaddr) * --- linux-xilinx-6.8.0.orig/arch/x86/xen/setup.c +++ linux-xilinx-6.8.0/arch/x86/xen/setup.c @@ -38,9 +38,6 @@ #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024) -/* Amount of extra memory space we add to the e820 ranges */ -struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata; - /* Number of pages released from the initial allocation. */ unsigned long xen_released_pages; @@ -64,18 +61,6 @@ } xen_remap_buf __initdata __aligned(PAGE_SIZE); static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY; -/* - * The maximum amount of extra memory compared to the base size. The - * main scaling factor is the size of struct page. At extreme ratios - * of base:extra, all the base memory can be filled with page - * structures for the extra memory, leaving no space for anything - * else. - * - * 10x seems like a reasonable balance between scaling flexibility and - * leaving a practically usable system. - */ -#define EXTRA_MEM_RATIO (10) - static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB); static void __init xen_parse_512gb(void) @@ -96,35 +81,6 @@ xen_512gb_limit = val; } -static void __init xen_add_extra_mem(unsigned long start_pfn, - unsigned long n_pfns) -{ - int i; - - /* - * No need to check for zero size, should happen rarely and will only - * write a new entry regarded to be unused due to zero size. - */ - for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { - /* Add new region. */ - if (xen_extra_mem[i].n_pfns == 0) { - xen_extra_mem[i].start_pfn = start_pfn; - xen_extra_mem[i].n_pfns = n_pfns; - break; - } - /* Append to existing region. */ - if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns == - start_pfn) { - xen_extra_mem[i].n_pfns += n_pfns; - break; - } - } - if (i == XEN_EXTRA_MEM_MAX_REGIONS) - printk(KERN_WARNING "Warning: not enough extra memory regions\n"); - - memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns)); -} - static void __init xen_del_extra_mem(unsigned long start_pfn, unsigned long n_pfns) { --- linux-xilinx-6.8.0.orig/arch/x86/xen/xen-ops.h +++ linux-xilinx-6.8.0/arch/x86/xen/xen-ops.h @@ -163,4 +163,18 @@ static inline void xen_hvm_post_suspend(int suspend_cancelled) {} #endif +/* + * The maximum amount of extra memory compared to the base size. The + * main scaling factor is the size of struct page. At extreme ratios + * of base:extra, all the base memory can be filled with page + * structures for the extra memory, leaving no space for anything + * else. + * + * 10x seems like a reasonable balance between scaling flexibility and + * leaving a practically usable system. + */ +#define EXTRA_MEM_RATIO (10) + +void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns); + #endif /* XEN_OPS_H */ --- linux-xilinx-6.8.0.orig/arch/xtensa/include/asm/processor.h +++ linux-xilinx-6.8.0/arch/xtensa/include/asm/processor.h @@ -115,9 +115,9 @@ #define MAKE_RA_FOR_CALL(ra,ws) (((ra) & 0x3fffffff) | (ws) << 30) /* Convert return address to a valid pc - * Note: We assume that the stack pointer is in the same 1GB ranges as the ra + * Note: 'text' is the address within the same 1GB range as the ra */ -#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) +#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000)) #elif defined(__XTENSA_CALL0_ABI__) @@ -127,9 +127,9 @@ #define MAKE_RA_FOR_CALL(ra, ws) (ra) /* Convert return address to a valid pc - * Note: We assume that the stack pointer is in the same 1GB ranges as the ra + * Note: 'text' is not used as 'ra' is always the full address */ -#define MAKE_PC_FROM_RA(ra, sp) (ra) +#define MAKE_PC_FROM_RA(ra, text) (ra) #else #error Unsupported Xtensa ABI --- linux-xilinx-6.8.0.orig/arch/xtensa/include/asm/ptrace.h +++ linux-xilinx-6.8.0/arch/xtensa/include/asm/ptrace.h @@ -87,7 +87,7 @@ # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) # define instruction_pointer(regs) ((regs)->pc) # define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \ - (regs)->areg[1])) + (regs)->pc)) # ifndef CONFIG_SMP # define profile_pc(regs) instruction_pointer(regs) --- linux-xilinx-6.8.0.orig/arch/xtensa/kernel/process.c +++ linux-xilinx-6.8.0/arch/xtensa/kernel/process.c @@ -47,6 +47,7 @@ #include #include #include +#include #include extern void ret_from_fork(void); @@ -380,7 +381,7 @@ int count = 0; sp = p->thread.sp; - pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp); + pc = MAKE_PC_FROM_RA(p->thread.ra, _text); do { if (sp < stack_page + sizeof(struct task_struct) || @@ -392,7 +393,7 @@ /* Stack layout: sp-4: ra, sp-3: sp' */ - pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp); + pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text); sp = SPILL_SLOT(sp, 1); } while (count++ < 16); return 0; --- linux-xilinx-6.8.0.orig/arch/xtensa/kernel/stacktrace.c +++ linux-xilinx-6.8.0/arch/xtensa/kernel/stacktrace.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -189,7 +190,7 @@ if (a1 <= (unsigned long)sp) break; - frame.pc = MAKE_PC_FROM_RA(a0, a1); + frame.pc = MAKE_PC_FROM_RA(a0, _text); frame.sp = a1; if (fn(&frame, data)) --- linux-xilinx-6.8.0.orig/block/bdev.c +++ linux-xilinx-6.8.0/block/bdev.c @@ -639,6 +639,14 @@ bdev_write_inode(bdev); } +static void blkdev_put_whole(struct block_device *bdev) +{ + if (atomic_dec_and_test(&bdev->bd_openers)) + blkdev_flush_mapping(bdev); + if (bdev->bd_disk->fops->release) + bdev->bd_disk->fops->release(bdev->bd_disk); +} + static int blkdev_get_whole(struct block_device *bdev, blk_mode_t mode) { struct gendisk *disk = bdev->bd_disk; @@ -657,20 +665,21 @@ if (!atomic_read(&bdev->bd_openers)) set_init_blocksize(bdev); - if (test_bit(GD_NEED_PART_SCAN, &disk->state)) - bdev_disk_changed(disk, false); atomic_inc(&bdev->bd_openers); + if (test_bit(GD_NEED_PART_SCAN, &disk->state)) { + /* + * Only return scanning errors if we are called from contexts + * that explicitly want them, e.g. the BLKRRPART ioctl. + */ + ret = bdev_disk_changed(disk, false); + if (ret && (mode & BLK_OPEN_STRICT_SCAN)) { + blkdev_put_whole(bdev); + return ret; + } + } return 0; } -static void blkdev_put_whole(struct block_device *bdev) -{ - if (atomic_dec_and_test(&bdev->bd_openers)) - blkdev_flush_mapping(bdev); - if (bdev->bd_disk->fops->release) - bdev->bd_disk->fops->release(bdev->bd_disk); -} - static int blkdev_get_part(struct block_device *part, blk_mode_t mode) { struct gendisk *disk = part->bd_disk; @@ -738,17 +747,17 @@ static bool bdev_writes_blocked(struct block_device *bdev) { - return bdev->bd_writers == -1; + return bdev->bd_writers < 0; } static void bdev_block_writes(struct block_device *bdev) { - bdev->bd_writers = -1; + bdev->bd_writers--; } static void bdev_unblock_writes(struct block_device *bdev) { - bdev->bd_writers = 0; + bdev->bd_writers++; } static bool bdev_may_open(struct block_device *bdev, blk_mode_t mode) @@ -864,7 +873,7 @@ goto abort_claiming; ret = -EBUSY; if (!bdev_may_open(bdev, mode)) - goto abort_claiming; + goto put_module; if (bdev_is_partition(bdev)) ret = blkdev_get_part(bdev, mode); else --- linux-xilinx-6.8.0.orig/block/bio.c +++ linux-xilinx-6.8.0/block/bio.c @@ -1152,7 +1152,7 @@ bio_for_each_folio_all(fi, bio) { struct page *page; - size_t done = 0; + size_t nr_pages; if (mark_dirty) { folio_lock(fi.folio); @@ -1160,10 +1160,11 @@ folio_unlock(fi.folio); } page = folio_page(fi.folio, fi.offset / PAGE_SIZE); + nr_pages = (fi.offset + fi.length - 1) / PAGE_SIZE - + fi.offset / PAGE_SIZE + 1; do { bio_release_page(bio, page++); - done += PAGE_SIZE; - } while (done < fi.length); + } while (--nr_pages != 0); } } EXPORT_SYMBOL_GPL(__bio_release_pages); --- linux-xilinx-6.8.0.orig/block/blk-cgroup.c +++ linux-xilinx-6.8.0/block/blk-cgroup.c @@ -323,6 +323,7 @@ blkg->q = disk->queue; INIT_LIST_HEAD(&blkg->q_node); blkg->blkcg = blkcg; + blkg->iostat.blkg = blkg; #ifdef CONFIG_BLK_CGROUP_PUNT_BIO spin_lock_init(&blkg->async_bio_lock); bio_list_init(&blkg->async_bios); @@ -619,12 +620,45 @@ spin_unlock_irq(&q->queue_lock); } +static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src) +{ + int i; + + for (i = 0; i < BLKG_IOSTAT_NR; i++) { + dst->bytes[i] = src->bytes[i]; + dst->ios[i] = src->ios[i]; + } +} + +static void __blkg_clear_stat(struct blkg_iostat_set *bis) +{ + struct blkg_iostat cur = {0}; + unsigned long flags; + + flags = u64_stats_update_begin_irqsave(&bis->sync); + blkg_iostat_set(&bis->cur, &cur); + blkg_iostat_set(&bis->last, &cur); + u64_stats_update_end_irqrestore(&bis->sync, flags); +} + +static void blkg_clear_stat(struct blkcg_gq *blkg) +{ + int cpu; + + for_each_possible_cpu(cpu) { + struct blkg_iostat_set *s = per_cpu_ptr(blkg->iostat_cpu, cpu); + + __blkg_clear_stat(s); + } + __blkg_clear_stat(&blkg->iostat); +} + static int blkcg_reset_stats(struct cgroup_subsys_state *css, struct cftype *cftype, u64 val) { struct blkcg *blkcg = css_to_blkcg(css); struct blkcg_gq *blkg; - int i, cpu; + int i; mutex_lock(&blkcg_pol_mutex); spin_lock_irq(&blkcg->lock); @@ -635,18 +669,7 @@ * anyway. If you get hit by a race, retry. */ hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) { - for_each_possible_cpu(cpu) { - struct blkg_iostat_set *bis = - per_cpu_ptr(blkg->iostat_cpu, cpu); - memset(bis, 0, sizeof(*bis)); - - /* Re-initialize the cleared blkg_iostat_set */ - u64_stats_init(&bis->sync); - bis->blkg = blkg; - } - memset(&blkg->iostat, 0, sizeof(blkg->iostat)); - u64_stats_init(&blkg->iostat.sync); - + blkg_clear_stat(blkg); for (i = 0; i < BLKCG_MAX_POLS; i++) { struct blkcg_policy *pol = blkcg_policy[i]; @@ -949,16 +972,6 @@ } EXPORT_SYMBOL_GPL(blkg_conf_exit); -static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src) -{ - int i; - - for (i = 0; i < BLKG_IOSTAT_NR; i++) { - dst->bytes[i] = src->bytes[i]; - dst->ios[i] = src->ios[i]; - } -} - static void blkg_iostat_add(struct blkg_iostat *dst, struct blkg_iostat *src) { int i; @@ -1024,7 +1037,19 @@ struct blkg_iostat cur; unsigned int seq; + /* + * Order assignment of `next_bisc` from `bisc->lnode.next` in + * llist_for_each_entry_safe and clearing `bisc->lqueued` for + * avoiding to assign `next_bisc` with new next pointer added + * in blk_cgroup_bio_start() in case of re-ordering. + * + * The pair barrier is implied in llist_add() in blk_cgroup_bio_start(). + */ + smp_mb(); + WRITE_ONCE(bisc->lqueued, false); + if (bisc == &blkg->iostat) + goto propagate_up; /* propagate up to parent only */ /* fetch the current per-cpu values */ do { @@ -1034,10 +1059,24 @@ blkcg_iostat_update(blkg, &cur, &bisc->last); +propagate_up: /* propagate global delta to parent (unless that's root) */ - if (parent && parent->parent) + if (parent && parent->parent) { blkcg_iostat_update(parent, &blkg->iostat.cur, &blkg->iostat.last); + /* + * Queue parent->iostat to its blkcg's lockless + * list to propagate up to the grandparent if the + * iostat hasn't been queued yet. + */ + if (!parent->iostat.lqueued) { + struct llist_head *plhead; + + plhead = per_cpu_ptr(parent->blkcg->lhead, cpu); + llist_add(&parent->iostat.lnode, plhead); + parent->iostat.lqueued = true; + } + } } raw_spin_unlock_irqrestore(&blkg_stat_lock, flags); out: @@ -1409,6 +1448,12 @@ return 0; } +void blkg_init_queue(struct request_queue *q) +{ + INIT_LIST_HEAD(&q->blkg_list); + mutex_init(&q->blkcg_mutex); +} + int blkcg_init_disk(struct gendisk *disk) { struct request_queue *q = disk->queue; @@ -1416,9 +1461,6 @@ bool preloaded; int ret; - INIT_LIST_HEAD(&q->blkg_list); - mutex_init(&q->blkcg_mutex); - new_blkg = blkg_alloc(&blkcg_root, disk, GFP_KERNEL); if (!new_blkg) return -ENOMEM; --- linux-xilinx-6.8.0.orig/block/blk-cgroup.h +++ linux-xilinx-6.8.0/block/blk-cgroup.h @@ -188,6 +188,7 @@ extern struct blkcg blkcg_root; extern bool blkcg_debug_stats; +void blkg_init_queue(struct request_queue *q); int blkcg_init_disk(struct gendisk *disk); void blkcg_exit_disk(struct gendisk *disk); @@ -481,6 +482,7 @@ }; static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; } +static inline void blkg_init_queue(struct request_queue *q) { } static inline int blkcg_init_disk(struct gendisk *disk) { return 0; } static inline void blkcg_exit_disk(struct gendisk *disk) { } static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; } --- linux-xilinx-6.8.0.orig/block/blk-core.c +++ linux-xilinx-6.8.0/block/blk-core.c @@ -431,6 +431,8 @@ init_waitqueue_head(&q->mq_freeze_wq); mutex_init(&q->mq_freeze_lock); + blkg_init_queue(q); + /* * Init percpu_ref in atomic mode so that it's faster to shutdown. * See blk_register_queue() for details. @@ -974,10 +976,11 @@ unsigned long stamp; again: stamp = READ_ONCE(part->bd_stamp); - if (unlikely(time_after(now, stamp))) { - if (likely(try_cmpxchg(&part->bd_stamp, &stamp, now))) - __part_stat_add(part, io_ticks, end ? now - stamp : 1); - } + if (unlikely(time_after(now, stamp)) && + likely(try_cmpxchg(&part->bd_stamp, &stamp, now)) && + (end || part_in_flight(part))) + __part_stat_add(part, io_ticks, now - stamp); + if (part->bd_partno) { part = bdev_whole(part); goto again; --- linux-xilinx-6.8.0.orig/block/blk-flush.c +++ linux-xilinx-6.8.0/block/blk-flush.c @@ -183,7 +183,7 @@ /* queue for flush */ if (list_empty(pending)) fq->flush_pending_since = jiffies; - list_move_tail(&rq->queuelist, pending); + list_add_tail(&rq->queuelist, pending); break; case REQ_FSEQ_DATA: @@ -261,6 +261,7 @@ unsigned int seq = blk_flush_cur_seq(rq); BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH); + list_del_init(&rq->queuelist); blk_flush_complete_seq(rq, fq, seq, error); } --- linux-xilinx-6.8.0.orig/block/blk-iocost.c +++ linux-xilinx-6.8.0/block/blk-iocost.c @@ -1347,7 +1347,7 @@ { struct ioc *ioc = iocg->ioc; struct blkcg_gq *blkg = iocg_to_blkg(iocg); - u64 tdelta, delay, new_delay; + u64 tdelta, delay, new_delay, shift; s64 vover, vover_pct; u32 hwa; @@ -1362,8 +1362,9 @@ /* calculate the current delay in effect - 1/2 every second */ tdelta = now->now - iocg->delay_at; - if (iocg->delay) - delay = iocg->delay >> div64_u64(tdelta, USEC_PER_SEC); + shift = div64_u64(tdelta, USEC_PER_SEC); + if (iocg->delay && shift < BITS_PER_LONG) + delay = iocg->delay >> shift; else delay = 0; @@ -1438,8 +1439,11 @@ lockdep_assert_held(&iocg->ioc->lock); lockdep_assert_held(&iocg->waitq.lock); - /* make sure that nobody messed with @iocg */ - WARN_ON_ONCE(list_empty(&iocg->active_list)); + /* + * make sure that nobody messed with @iocg. Check iocg->pd.online + * to avoid warn when removing blkcg or disk. + */ + WARN_ON_ONCE(list_empty(&iocg->active_list) && iocg->pd.online); WARN_ON_ONCE(iocg->inuse > 1); iocg->abs_vdebt -= min(abs_vpay, iocg->abs_vdebt); --- linux-xilinx-6.8.0.orig/block/blk-merge.c +++ linux-xilinx-6.8.0/block/blk-merge.c @@ -779,6 +779,8 @@ if (blk_do_io_stat(req)) { part_stat_lock(); part_stat_inc(req->part, merges[op_stat_group(req_op(req))]); + part_stat_local_dec(req->part, + in_flight[op_is_write(req_op(req))]); part_stat_unlock(); } } --- linux-xilinx-6.8.0.orig/block/blk-mq.c +++ linux-xilinx-6.8.0/block/blk-mq.c @@ -771,16 +771,11 @@ /* * Partial zone append completions cannot be supported as the * BIO fragments may end up not being written sequentially. - * For such case, force the completed nbytes to be equal to - * the BIO size so that bio_advance() sets the BIO remaining - * size to 0 and we end up calling bio_endio() before returning. */ - if (bio->bi_iter.bi_size != nbytes) { + if (bio->bi_iter.bi_size != nbytes) bio->bi_status = BLK_STS_IOERR; - nbytes = bio->bi_iter.bi_size; - } else { + else bio->bi_iter.bi_sector = rq->__sector; - } } bio_advance(bio, nbytes); @@ -1003,6 +998,8 @@ update_io_ticks(req->part, jiffies, true); part_stat_inc(req->part, ios[sgrp]); part_stat_add(req->part, nsecs[sgrp], now - req->start_time_ns); + part_stat_local_dec(req->part, + in_flight[op_is_write(req_op(req))]); part_stat_unlock(); } } @@ -1025,6 +1022,8 @@ part_stat_lock(); update_io_ticks(req->part, jiffies, false); + part_stat_local_inc(req->part, + in_flight[op_is_write(req_op(req))]); part_stat_unlock(); } } --- linux-xilinx-6.8.0.orig/block/blk-settings.c +++ linux-xilinx-6.8.0/block/blk-settings.c @@ -559,6 +559,8 @@ unsigned int top, bottom, alignment, ret = 0; t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); + t->max_user_sectors = min_not_zero(t->max_user_sectors, + b->max_user_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors); t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors, @@ -689,6 +691,10 @@ t->zone_write_granularity = max(t->zone_write_granularity, b->zone_write_granularity); t->zoned = max(t->zoned, b->zoned); + if (!t->zoned) { + t->zone_write_granularity = 0; + t->max_zone_append_sectors = 0; + } return ret; } EXPORT_SYMBOL(blk_stack_limits); --- linux-xilinx-6.8.0.orig/block/blk-stat.c +++ linux-xilinx-6.8.0/block/blk-stat.c @@ -27,7 +27,7 @@ /* src is a per-cpu stat, mean isn't initialized */ void blk_rq_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src) { - if (!src->nr_samples) + if (dst->nr_samples + src->nr_samples <= dst->nr_samples) return; dst->min = min(dst->min, src->min); --- linux-xilinx-6.8.0.orig/block/blk.h +++ linux-xilinx-6.8.0/block/blk.h @@ -344,6 +344,7 @@ } void update_io_ticks(struct block_device *part, unsigned long now, bool end); +unsigned int part_in_flight(struct block_device *part); static inline void req_set_nomerge(struct request_queue *q, struct request *req) { --- linux-xilinx-6.8.0.orig/block/fops.c +++ linux-xilinx-6.8.0/block/fops.c @@ -387,7 +387,7 @@ iomap->bdev = bdev; iomap->offset = ALIGN_DOWN(offset, bdev_logical_block_size(bdev)); - if (iomap->offset >= isize) + if (offset >= isize) return -EIO; iomap->type = IOMAP_MAPPED; iomap->addr = iomap->offset; --- linux-xilinx-6.8.0.orig/block/genhd.c +++ linux-xilinx-6.8.0/block/genhd.c @@ -118,7 +118,7 @@ } } -static unsigned int part_in_flight(struct block_device *part) +unsigned int part_in_flight(struct block_device *part) { unsigned int inflight = 0; int cpu; @@ -345,9 +345,7 @@ struct bdev_handle *handle; int ret = 0; - if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN)) - return -EINVAL; - if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state)) + if (!disk_has_partscan(disk)) return -EINVAL; if (disk->open_partitions) return -EBUSY; @@ -503,8 +501,7 @@ goto out_unregister_bdi; /* Make sure the first partition scan will be proceed */ - if (get_capacity(disk) && !(disk->flags & GENHD_FL_NO_PART) && - !test_bit(GD_SUPPRESS_PART_SCAN, &disk->state)) + if (get_capacity(disk) && disk_has_partscan(disk)) set_bit(GD_NEED_PART_SCAN, &disk->state); bdev_add(disk->part0, ddev->devt); @@ -1047,6 +1044,12 @@ return sprintf(buf, "%llu\n", disk->diskseq); } +static ssize_t partscan_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", disk_has_partscan(dev_to_disk(dev))); +} + static DEVICE_ATTR(range, 0444, disk_range_show, NULL); static DEVICE_ATTR(ext_range, 0444, disk_ext_range_show, NULL); static DEVICE_ATTR(removable, 0444, disk_removable_show, NULL); @@ -1060,6 +1063,7 @@ static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL); static DEVICE_ATTR(badblocks, 0644, disk_badblocks_show, disk_badblocks_store); static DEVICE_ATTR(diskseq, 0444, diskseq_show, NULL); +static DEVICE_ATTR(partscan, 0444, partscan_show, NULL); #ifdef CONFIG_FAIL_MAKE_REQUEST ssize_t part_fail_show(struct device *dev, @@ -1106,6 +1110,7 @@ &dev_attr_events_async.attr, &dev_attr_events_poll_msecs.attr, &dev_attr_diskseq.attr, + &dev_attr_partscan.attr, #ifdef CONFIG_FAIL_MAKE_REQUEST &dev_attr_fail.attr, #endif --- linux-xilinx-6.8.0.orig/block/holder.c +++ linux-xilinx-6.8.0/block/holder.c @@ -8,6 +8,8 @@ int refcnt; }; +static DEFINE_MUTEX(blk_holder_mutex); + static struct bd_holder_disk *bd_find_holder_disk(struct block_device *bdev, struct gendisk *disk) { @@ -80,7 +82,7 @@ kobject_get(bdev->bd_holder_dir); mutex_unlock(&bdev->bd_disk->open_mutex); - mutex_lock(&disk->open_mutex); + mutex_lock(&blk_holder_mutex); WARN_ON_ONCE(!bdev->bd_holder); holder = bd_find_holder_disk(bdev, disk); @@ -108,7 +110,7 @@ goto out_del_symlink; list_add(&holder->list, &disk->slave_bdevs); - mutex_unlock(&disk->open_mutex); + mutex_unlock(&blk_holder_mutex); return 0; out_del_symlink: @@ -116,7 +118,7 @@ out_free_holder: kfree(holder); out_unlock: - mutex_unlock(&disk->open_mutex); + mutex_unlock(&blk_holder_mutex); if (ret) kobject_put(bdev->bd_holder_dir); return ret; @@ -140,7 +142,7 @@ if (WARN_ON_ONCE(!disk->slave_dir)) return; - mutex_lock(&disk->open_mutex); + mutex_lock(&blk_holder_mutex); holder = bd_find_holder_disk(bdev, disk); if (!WARN_ON_ONCE(holder == NULL) && !--holder->refcnt) { del_symlink(disk->slave_dir, bdev_kobj(bdev)); @@ -149,6 +151,6 @@ list_del_init(&holder->list); kfree(holder); } - mutex_unlock(&disk->open_mutex); + mutex_unlock(&blk_holder_mutex); } EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); --- linux-xilinx-6.8.0.orig/block/ioctl.c +++ linux-xilinx-6.8.0/block/ioctl.c @@ -33,7 +33,7 @@ if (op == BLKPG_DEL_PARTITION) return bdev_del_partition(disk, p.pno); - if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) + if (p.start < 0 || p.length <= 0 || LLONG_MAX - p.length < p.start) return -EINVAL; /* Check that the partition is aligned to the block size */ if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) @@ -89,7 +89,7 @@ unsigned long arg) { uint64_t range[2]; - uint64_t start, len; + uint64_t start, len, end; struct inode *inode = bdev->bd_inode; int err; @@ -110,7 +110,8 @@ if (len & 511) return -EINVAL; - if (start + len > bdev_nr_bytes(bdev)) + if (check_add_overflow(start, len, &end) || + end > bdev_nr_bytes(bdev)) return -EINVAL; filemap_invalidate_lock(inode->i_mapping); @@ -556,7 +557,8 @@ return -EACCES; if (bdev_is_partition(bdev)) return -EINVAL; - return disk_scan_partitions(bdev->bd_disk, mode); + return disk_scan_partitions(bdev->bd_disk, + mode | BLK_OPEN_STRICT_SCAN); case BLKTRACESTART: case BLKTRACESTOP: case BLKTRACETEARDOWN: --- linux-xilinx-6.8.0.orig/block/mq-deadline.c +++ linux-xilinx-6.8.0/block/mq-deadline.c @@ -646,9 +646,8 @@ struct request_queue *q = hctx->queue; struct deadline_data *dd = q->elevator->elevator_data; struct blk_mq_tags *tags = hctx->sched_tags; - unsigned int shift = tags->bitmap_tags.sb.shift; - dd->async_depth = max(1U, 3 * (1U << shift) / 4); + dd->async_depth = max(1UL, 3 * q->nr_requests / 4); sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth); } --- linux-xilinx-6.8.0.orig/block/partitions/cmdline.c +++ linux-xilinx-6.8.0/block/partitions/cmdline.c @@ -70,8 +70,8 @@ } if (*partdef == '(') { - int length; - char *next = strchr(++partdef, ')'); + partdef++; + char *next = strsep(&partdef, ")"); if (!next) { pr_warn("cmdline partition format is invalid."); @@ -79,11 +79,7 @@ goto fail; } - length = min_t(int, next - partdef, - sizeof(new_subpart->name) - 1); - strscpy(new_subpart->name, partdef, length); - - partdef = ++next; + strscpy(new_subpart->name, next, sizeof(new_subpart->name)); } else new_subpart->name[0] = '\0'; @@ -117,14 +113,12 @@ } } -static int parse_parts(struct cmdline_parts **parts, const char *bdevdef) +static int parse_parts(struct cmdline_parts **parts, char *bdevdef) { int ret = -EINVAL; char *next; - int length; struct cmdline_subpart **next_subpart; struct cmdline_parts *newparts; - char buf[BDEVNAME_SIZE + 32 + 4]; *parts = NULL; @@ -132,28 +126,19 @@ if (!newparts) return -ENOMEM; - next = strchr(bdevdef, ':'); + next = strsep(&bdevdef, ":"); if (!next) { pr_warn("cmdline partition has no block device."); goto fail; } - length = min_t(int, next - bdevdef, sizeof(newparts->name) - 1); - strscpy(newparts->name, bdevdef, length); + strscpy(newparts->name, next, sizeof(newparts->name)); newparts->nr_subparts = 0; next_subpart = &newparts->subpart; - while (next && *(++next)) { - bdevdef = next; - next = strchr(bdevdef, ','); - - length = (!next) ? (sizeof(buf) - 1) : - min_t(int, next - bdevdef, sizeof(buf) - 1); - - strscpy(buf, bdevdef, length); - - ret = parse_subpart(next_subpart, buf); + while ((next = strsep(&bdevdef, ","))) { + ret = parse_subpart(next_subpart, next); if (ret) goto fail; @@ -199,24 +184,17 @@ *parts = NULL; - next = pbuf = buf = kstrdup(cmdline, GFP_KERNEL); + pbuf = buf = kstrdup(cmdline, GFP_KERNEL); if (!buf) return -ENOMEM; next_parts = parts; - while (next && *pbuf) { - next = strchr(pbuf, ';'); - if (next) - *next = '\0'; - - ret = parse_parts(next_parts, pbuf); + while ((next = strsep(&pbuf, ";"))) { + ret = parse_parts(next_parts, next); if (ret) goto fail; - if (next) - pbuf = ++next; - next_parts = &(*next_parts)->next_parts; } @@ -250,7 +228,6 @@ static int add_part(int slot, struct cmdline_subpart *subpart, struct parsed_partitions *state) { - int label_min; struct partition_meta_info *info; char tmp[sizeof(info->volname) + 4]; @@ -262,9 +239,7 @@ info = &state->parts[slot].info; - label_min = min_t(int, sizeof(info->volname) - 1, - sizeof(subpart->name)); - strscpy(info->volname, subpart->name, label_min); + strscpy(info->volname, subpart->name, sizeof(info->volname)); snprintf(tmp, sizeof(tmp), "(%s)", info->volname); strlcat(state->pp_buf, tmp, PAGE_SIZE); --- linux-xilinx-6.8.0.orig/block/partitions/core.c +++ linux-xilinx-6.8.0/block/partitions/core.c @@ -584,10 +584,7 @@ struct parsed_partitions *state; int ret = -EAGAIN, p; - if (disk->flags & GENHD_FL_NO_PART) - return 0; - - if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state)) + if (!disk_has_partscan(disk)) return 0; state = check_partition(disk); --- linux-xilinx-6.8.0.orig/block/sed-opal.c +++ linux-xilinx-6.8.0/block/sed-opal.c @@ -314,7 +314,7 @@ &key_type_user, key_name, true); if (IS_ERR(kref)) - ret = PTR_ERR(kref); + return PTR_ERR(kref); key = key_ref_to_ptr(kref); down_read(&key->sem); --- linux-xilinx-6.8.0.orig/certs/blacklist.c +++ linux-xilinx-6.8.0/certs/blacklist.c @@ -276,6 +276,9 @@ if (IS_ERR(key)) { pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); return PTR_ERR(key); + } else { + pr_notice("Revoked X.509 cert '%s'\n", + key_ref_to_ptr(key)->description); } return 0; --- linux-xilinx-6.8.0.orig/crypto/Kconfig +++ linux-xilinx-6.8.0/crypto/Kconfig @@ -1269,10 +1269,11 @@ A non-physical non-deterministic ("true") RNG (e.g., an entropy source compliant with NIST SP800-90B) intended to provide a seed to a - deterministic RNG (e.g. per NIST SP800-90C). + deterministic RNG (e.g., per NIST SP800-90C). This RNG does not perform any cryptographic whitening of the generated + random numbers. - See https://www.chronox.de/jent.html + See https://www.chronox.de/jent/ if CRYPTO_JITTERENTROPY if CRYPTO_FIPS && EXPERT --- linux-xilinx-6.8.0.orig/crypto/aead.c +++ linux-xilinx-6.8.0/crypto/aead.c @@ -45,8 +45,7 @@ alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); memcpy(alignbuffer, key, keylen); ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen); - memset(alignbuffer, 0, keylen); - kfree(buffer); + kfree_sensitive(buffer); return ret; } --- linux-xilinx-6.8.0.orig/crypto/aegis128-neon-inner.c +++ linux-xilinx-6.8.0/crypto/aegis128-neon-inner.c @@ -148,8 +148,8 @@ kiv, vld1q_u8(const1), vld1q_u8(const0), - k ^ vld1q_u8(const0), - k ^ vld1q_u8(const1), + (uint8x16_t) (k ^ vld1q_u8(const0)), + (uint8x16_t) (k ^ vld1q_u8(const1)), }}; int i; --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/Kconfig +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/Kconfig @@ -15,6 +15,7 @@ select MPILIB select CRYPTO_HASH_INFO select CRYPTO_AKCIPHER + select CRYPTO_SIG select CRYPTO_HASH help This option provides support for asymmetric public key type handling. @@ -85,5 +86,7 @@ depends on ASYMMETRIC_KEY_TYPE depends on PKCS7_MESSAGE_PARSER=X509_CERTIFICATE_PARSER depends on X509_CERTIFICATE_PARSER + depends on CRYPTO_RSA + depends on CRYPTO_SHA256 endif # ASYMMETRIC_KEY_TYPE --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/mscode_parser.c +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/mscode_parser.c @@ -75,6 +75,9 @@ oid = look_up_OID(value, vlen); switch (oid) { + case OID_sha1: + ctx->digest_algo = "sha1"; + break; case OID_sha256: ctx->digest_algo = "sha256"; break; --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/pkcs7_parser.c +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/pkcs7_parser.c @@ -227,6 +227,9 @@ struct pkcs7_parse_context *ctx = context; switch (ctx->last_oid) { + case OID_sha1: + ctx->sinfo->sig->hash_algo = "sha1"; + break; case OID_sha256: ctx->sinfo->sig->hash_algo = "sha256"; break; @@ -278,6 +281,7 @@ ctx->sinfo->sig->pkey_algo = "rsa"; ctx->sinfo->sig->encoding = "pkcs1"; break; + case OID_id_ecdsa_with_sha1: case OID_id_ecdsa_with_sha224: case OID_id_ecdsa_with_sha256: case OID_id_ecdsa_with_sha384: --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/public_key.c +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/public_key.c @@ -115,7 +115,8 @@ */ if (!hash_algo) return -EINVAL; - if (strcmp(hash_algo, "sha224") != 0 && + if (strcmp(hash_algo, "sha1") != 0 && + strcmp(hash_algo, "sha224") != 0 && strcmp(hash_algo, "sha256") != 0 && strcmp(hash_algo, "sha384") != 0 && strcmp(hash_algo, "sha512") != 0 && @@ -233,6 +234,7 @@ info->key_size = len * 8; if (strncmp(pkey->pkey_algo, "ecdsa", 5) == 0) { + int slen = len; /* * ECDSA key sizes are much smaller than RSA, and thus could * operate on (hashed) inputs that are larger than key size. @@ -246,8 +248,19 @@ * Verify takes ECDSA-Sig (described in RFC 5480) as input, * which is actually 2 'key_size'-bit integers encoded in * ASN.1. Account for the ASN.1 encoding overhead here. + * + * NIST P192/256/384 may prepend a '0' to a coordinate to + * indicate a positive integer. NIST P521 never needs it. */ - info->max_sig_size = 2 * (len + 3) + 2; + if (strcmp(pkey->pkey_algo, "ecdsa-nist-p521") != 0) + slen += 1; + /* Length of encoding the x & y coordinates */ + slen = 2 * (slen + 2); + /* + * If coordinate encoding takes at least 128 bytes then an + * additional byte for length encoding is needed. + */ + info->max_sig_size = 1 + (slen >= 128) + 1 + slen; } else { info->max_data_size = len; info->max_sig_size = len; --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/signature.c +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/signature.c @@ -115,7 +115,7 @@ * Sign the specified data blob using the private key specified by params->key. * The signature is wrapped in an encoding if params->encoding is specified * (eg. "pkcs1"). If the encoding needs to know the digest type, this can be - * passed through params->hash_algo (eg. "sha512"). + * passed through params->hash_algo (eg. "sha1"). * * Returns the length of the data placed in the signature buffer or an error. */ --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/x509_cert_parser.c +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/x509_cert_parser.c @@ -198,6 +198,10 @@ default: return -ENOPKG; /* Unsupported combination */ + case OID_sha1WithRSAEncryption: + ctx->cert->sig->hash_algo = "sha1"; + goto rsa_pkcs1; + case OID_sha256WithRSAEncryption: ctx->cert->sig->hash_algo = "sha256"; goto rsa_pkcs1; @@ -214,6 +218,10 @@ ctx->cert->sig->hash_algo = "sha224"; goto rsa_pkcs1; + case OID_id_ecdsa_with_sha1: + ctx->cert->sig->hash_algo = "sha1"; + goto ecdsa; + case OID_id_rsassa_pkcs1_v1_5_with_sha3_256: ctx->cert->sig->hash_algo = "sha3-256"; goto rsa_pkcs1; @@ -538,6 +546,9 @@ case OID_id_ansip384r1: ctx->cert->pub->pkey_algo = "ecdsa-nist-p384"; break; + case OID_id_ansip521r1: + ctx->cert->pub->pkey_algo = "ecdsa-nist-p521"; + break; default: return -ENOPKG; } --- linux-xilinx-6.8.0.orig/crypto/asymmetric_keys/x509_loader.c +++ linux-xilinx-6.8.0/crypto/asymmetric_keys/x509_loader.c @@ -41,6 +41,7 @@ if (IS_ERR(key)) { pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", PTR_ERR(key)); + WARN_ON_ONCE(1); } else { pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description); --- linux-xilinx-6.8.0.orig/crypto/cipher.c +++ linux-xilinx-6.8.0/crypto/cipher.c @@ -34,8 +34,7 @@ alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); memcpy(alignbuffer, key, keylen); ret = cia->cia_setkey(crypto_cipher_tfm(tfm), alignbuffer, keylen); - memset(alignbuffer, 0, keylen); - kfree(buffer); + kfree_sensitive(buffer); return ret; } --- linux-xilinx-6.8.0.orig/crypto/ecc.c +++ linux-xilinx-6.8.0/crypto/ecc.c @@ -60,6 +60,8 @@ return &nist_p256; case ECC_CURVE_NIST_P384: return &nist_p384; + case ECC_CURVE_NIST_P521: + return &nist_p521; default: return NULL; } @@ -689,7 +691,7 @@ static void vli_mmod_fast_192(u64 *result, const u64 *product, const u64 *curve_prime, u64 *tmp) { - const unsigned int ndigits = 3; + const unsigned int ndigits = ECC_CURVE_NIST_P192_DIGITS; int carry; vli_set(result, product, ndigits); @@ -717,7 +719,7 @@ const u64 *curve_prime, u64 *tmp) { int carry; - const unsigned int ndigits = 4; + const unsigned int ndigits = ECC_CURVE_NIST_P256_DIGITS; /* t */ vli_set(result, product, ndigits); @@ -800,7 +802,7 @@ const u64 *curve_prime, u64 *tmp) { int carry; - const unsigned int ndigits = 6; + const unsigned int ndigits = ECC_CURVE_NIST_P384_DIGITS; /* t */ vli_set(result, product, ndigits); @@ -902,6 +904,28 @@ #undef AND64H #undef AND64L +/* + * Computes result = product % curve_prime + * from "Recommendations for Discrete Logarithm-Based Cryptography: + * Elliptic Curve Domain Parameters" section G.1.4 + */ +static void vli_mmod_fast_521(u64 *result, const u64 *product, + const u64 *curve_prime, u64 *tmp) +{ + const unsigned int ndigits = ECC_CURVE_NIST_P521_DIGITS; + size_t i; + + /* Initialize result with lowest 521 bits from product */ + vli_set(result, product, ndigits); + result[8] &= 0x1ff; + + for (i = 0; i < ndigits; i++) + tmp[i] = (product[8 + i] >> 9) | (product[9 + i] << 55); + tmp[8] &= 0x1ff; + + vli_mod_add(result, result, tmp, curve_prime, ndigits); +} + /* Computes result = product % curve_prime for different curve_primes. * * Note that curve_primes are distinguished just by heuristic check and @@ -932,15 +956,18 @@ } switch (ndigits) { - case 3: + case ECC_CURVE_NIST_P192_DIGITS: vli_mmod_fast_192(result, product, curve_prime, tmp); break; - case 4: + case ECC_CURVE_NIST_P256_DIGITS: vli_mmod_fast_256(result, product, curve_prime, tmp); break; - case 6: + case ECC_CURVE_NIST_P384_DIGITS: vli_mmod_fast_384(result, product, curve_prime, tmp); break; + case ECC_CURVE_NIST_P521_DIGITS: + vli_mmod_fast_521(result, product, curve_prime, tmp); + break; default: pr_err_ratelimited("ecc: unsupported digits size!\n"); return false; @@ -1295,7 +1322,10 @@ carry = vli_add(sk[0], scalar, curve->n, ndigits); vli_add(sk[1], sk[0], curve->n, ndigits); scalar = sk[!carry]; - num_bits = sizeof(u64) * ndigits * 8 + 1; + if (curve->nbits == 521) /* NIST P521 */ + num_bits = curve->nbits + 2; + else + num_bits = sizeof(u64) * ndigits * 8 + 1; vli_set(rx[1], point->x, ndigits); vli_set(ry[1], point->y, ndigits); --- linux-xilinx-6.8.0.orig/crypto/ecc_curve_defs.h +++ linux-xilinx-6.8.0/crypto/ecc_curve_defs.h @@ -17,6 +17,7 @@ 0x64210519E59C80E7ull }; static struct ecc_curve nist_p192 = { .name = "nist_192", + .nbits = 192, .g = { .x = nist_p192_g_x, .y = nist_p192_g_y, @@ -43,6 +44,7 @@ 0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull }; static struct ecc_curve nist_p256 = { .name = "nist_256", + .nbits = 256, .g = { .x = nist_p256_g_x, .y = nist_p256_g_y, @@ -75,6 +77,7 @@ 0x988e056be3f82d19ull, 0xb3312fa7e23ee7e4ull }; static struct ecc_curve nist_p384 = { .name = "nist_384", + .nbits = 384, .g = { .x = nist_p384_g_x, .y = nist_p384_g_y, @@ -86,6 +89,51 @@ .b = nist_p384_b }; +/* NIST P-521 */ +static u64 nist_p521_g_x[] = { 0xf97e7e31c2e5bd66ull, 0x3348b3c1856a429bull, + 0xfe1dc127a2ffa8deull, 0xa14b5e77efe75928ull, + 0xf828af606b4d3dbaull, 0x9c648139053fb521ull, + 0x9e3ecb662395b442ull, 0x858e06b70404e9cdull, + 0xc6ull }; +static u64 nist_p521_g_y[] = { 0x88be94769fd16650ull, 0x353c7086a272c240ull, + 0xc550b9013fad0761ull, 0x97ee72995ef42640ull, + 0x17afbd17273e662cull, 0x98f54449579b4468ull, + 0x5c8a5fb42c7d1bd9ull, 0x39296a789a3bc004ull, + 0x118ull }; +static u64 nist_p521_p[] = { 0xffffffffffffffffull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0x1ffull }; +static u64 nist_p521_n[] = { 0xbb6fb71e91386409ull, 0x3bb5c9b8899c47aeull, + 0x7fcc0148f709a5d0ull, 0x51868783bf2f966bull, + 0xfffffffffffffffaull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0x1ffull }; +static u64 nist_p521_a[] = { 0xfffffffffffffffcull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0xffffffffffffffffull, 0xffffffffffffffffull, + 0x1ffull }; +static u64 nist_p521_b[] = { 0xef451fd46b503f00ull, 0x3573df883d2c34f1ull, + 0x1652c0bd3bb1bf07ull, 0x56193951ec7e937bull, + 0xb8b489918ef109e1ull, 0xa2da725b99b315f3ull, + 0x929a21a0b68540eeull, 0x953eb9618e1c9a1full, + 0x051ull }; +static struct ecc_curve nist_p521 = { + .name = "nist_521", + .nbits = 521, + .g = { + .x = nist_p521_g_x, + .y = nist_p521_g_y, + .ndigits = 9, + }, + .p = nist_p521_p, + .n = nist_p521_n, + .a = nist_p521_a, + .b = nist_p521_b +}; + /* curve25519 */ static u64 curve25519_g_x[] = { 0x0000000000000009, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }; @@ -95,6 +143,7 @@ 0x0000000000000000, 0x0000000000000000 }; static const struct ecc_curve ecc_25519 = { .name = "curve25519", + .nbits = 255, .g = { .x = curve25519_g_x, .ndigits = 4, --- linux-xilinx-6.8.0.orig/crypto/ecdh.c +++ linux-xilinx-6.8.0/crypto/ecdh.c @@ -33,6 +33,8 @@ params.key_size > sizeof(u64) * ctx->ndigits) return -EINVAL; + memset(ctx->private_key, 0, sizeof(ctx->private_key)); + if (!params.key || !params.key_size) return ecc_gen_privkey(ctx->curve_id, ctx->ndigits, ctx->private_key); --- linux-xilinx-6.8.0.orig/crypto/ecdsa.c +++ linux-xilinx-6.8.0/crypto/ecdsa.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -23,20 +24,14 @@ struct ecc_point pub_key; }; -struct ecdsa_signature_ctx { - const struct ecc_curve *curve; - u64 r[ECC_MAX_DIGITS]; - u64 s[ECC_MAX_DIGITS]; -}; - /* * Get the r and s components of a signature from the X509 certificate. */ -static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, - const void *value, size_t vlen, unsigned int ndigits) +int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen, unsigned int ndigits) { - size_t keylen = ndigits * sizeof(u64); - ssize_t diff = vlen - keylen; + size_t bufsize = ndigits * sizeof(u64); + ssize_t diff = vlen - bufsize; const char *d = value; u8 rs[ECC_MAX_BYTES]; @@ -58,7 +53,7 @@ if (diff) return -EINVAL; } - if (-diff >= keylen) + if (-diff >= bufsize) return -EINVAL; if (diff) { @@ -72,6 +67,7 @@ return 0; } +EXPORT_SYMBOL(ecdsa_get_signature_rs); int ecdsa_get_signature_r(void *context, size_t hdrlen, unsigned char tag, const void *value, size_t vlen) @@ -122,7 +118,7 @@ /* res.x = res.x mod n (if res.x > order) */ if (unlikely(vli_cmp(res.x, curve->n, ndigits) == 1)) - /* faster alternative for NIST p384, p256 & p192 */ + /* faster alternative for NIST p521, p384, p256 & p192 */ vli_sub(res.x, res.x, curve->n, ndigits); if (!vli_cmp(res.x, r, ndigits)) @@ -138,7 +134,7 @@ { struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); - size_t keylen = ctx->curve->g.ndigits * sizeof(u64); + size_t bufsize = ctx->curve->g.ndigits * sizeof(u64); struct ecdsa_signature_ctx sig_ctx = { .curve = ctx->curve, }; @@ -165,14 +161,14 @@ goto error; /* if the hash is shorter then we will add leading zeros to fit to ndigits */ - diff = keylen - req->dst_len; + diff = bufsize - req->dst_len; if (diff >= 0) { if (diff) memset(rawhash, 0, diff); memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len); } else if (diff < 0) { /* given hash is longer, we take the left-most bytes */ - memcpy(&rawhash, buffer + req->src_len, keylen); + memcpy(&rawhash, buffer + req->src_len, bufsize); } ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits); @@ -222,28 +218,32 @@ static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) { struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); + unsigned int digitlen, ndigits; const unsigned char *d = key; - const u64 *digits = (const u64 *)&d[1]; - unsigned int ndigits; int ret; ret = ecdsa_ecc_ctx_reset(ctx); if (ret < 0) return ret; - if (keylen < 1 || (((keylen - 1) >> 1) % sizeof(u64)) != 0) + if (keylen < 1 || ((keylen - 1) & 1) != 0) return -EINVAL; /* we only accept uncompressed format indicated by '4' */ if (d[0] != 4) return -EINVAL; keylen--; - ndigits = (keylen >> 1) / sizeof(u64); + digitlen = keylen >> 1; + + ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); if (ndigits != ctx->curve->g.ndigits) return -EINVAL; - ecc_swap_digits(digits, ctx->pub_key.x, ndigits); - ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits); + d++; + + ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits); + ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits); + ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key); ctx->pub_key_set = ret == 0; @@ -262,9 +262,31 @@ { struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); - return ctx->pub_key.ndigits << ECC_DIGITS_TO_BYTES_SHIFT; + return DIV_ROUND_UP(ctx->curve->nbits, 8); } +static int ecdsa_nist_p521_init_tfm(struct crypto_akcipher *tfm) +{ + struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); + + return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P521); +} + +static struct akcipher_alg ecdsa_nist_p521 = { + .verify = ecdsa_verify, + .set_pub_key = ecdsa_set_pub_key, + .max_size = ecdsa_max_size, + .init = ecdsa_nist_p521_init_tfm, + .exit = ecdsa_exit_tfm, + .base = { + .cra_name = "ecdsa-nist-p521", + .cra_driver_name = "ecdsa-nist-p521-generic", + .cra_priority = 100, + .cra_module = THIS_MODULE, + .cra_ctxsize = sizeof(struct ecc_ctx), + }, +}; + static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm) { struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); @@ -348,8 +370,15 @@ if (ret) goto nist_p384_error; + ret = crypto_register_akcipher(&ecdsa_nist_p521); + if (ret) + goto nist_p521_error; + return 0; +nist_p521_error: + crypto_unregister_akcipher(&ecdsa_nist_p384); + nist_p384_error: crypto_unregister_akcipher(&ecdsa_nist_p256); @@ -365,6 +394,7 @@ crypto_unregister_akcipher(&ecdsa_nist_p192); crypto_unregister_akcipher(&ecdsa_nist_p256); crypto_unregister_akcipher(&ecdsa_nist_p384); + crypto_unregister_akcipher(&ecdsa_nist_p521); } subsys_initcall(ecdsa_init); @@ -373,4 +403,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Stefan Berger "); MODULE_DESCRIPTION("ECDSA generic algorithm"); +MODULE_ALIAS_CRYPTO("ecdsa-nist-p192"); +MODULE_ALIAS_CRYPTO("ecdsa-nist-p256"); +MODULE_ALIAS_CRYPTO("ecdsa-nist-p384"); MODULE_ALIAS_CRYPTO("ecdsa-generic"); --- linux-xilinx-6.8.0.orig/crypto/ecrdsa.c +++ linux-xilinx-6.8.0/crypto/ecrdsa.c @@ -294,4 +294,5 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Vitaly Chikunov "); MODULE_DESCRIPTION("EC-RDSA generic algorithm"); +MODULE_ALIAS_CRYPTO("ecrdsa"); MODULE_ALIAS_CRYPTO("ecrdsa-generic"); --- linux-xilinx-6.8.0.orig/crypto/ecrdsa_defs.h +++ linux-xilinx-6.8.0/crypto/ecrdsa_defs.h @@ -47,6 +47,7 @@ static struct ecc_curve gost_cp256a = { .name = "cp256a", + .nbits = 256, .g = { .x = cp256a_g_x, .y = cp256a_g_y, @@ -80,6 +81,7 @@ static struct ecc_curve gost_cp256b = { .name = "cp256b", + .nbits = 256, .g = { .x = cp256b_g_x, .y = cp256b_g_y, @@ -117,6 +119,7 @@ static struct ecc_curve gost_cp256c = { .name = "cp256c", + .nbits = 256, .g = { .x = cp256c_g_x, .y = cp256c_g_y, @@ -166,6 +169,7 @@ static struct ecc_curve gost_tc512a = { .name = "tc512a", + .nbits = 512, .g = { .x = tc512a_g_x, .y = tc512a_g_y, @@ -211,6 +215,7 @@ static struct ecc_curve gost_tc512b = { .name = "tc512b", + .nbits = 512, .g = { .x = tc512b_g_x, .y = tc512b_g_y, --- linux-xilinx-6.8.0.orig/crypto/fips.c +++ linux-xilinx-6.8.0/crypto/fips.c @@ -14,7 +14,8 @@ #include #include -int fips_enabled; +/* LP: #2049082 UBUNTU: SAUCE: FIPS kernels default to FIPS mode */ +int fips_enabled = 1; EXPORT_SYMBOL_GPL(fips_enabled); ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain); --- linux-xilinx-6.8.0.orig/crypto/testmgr.c +++ linux-xilinx-6.8.0/crypto/testmgr.c @@ -5098,6 +5098,13 @@ .akcipher = __VECS(ecdsa_nist_p384_tv_template) } }, { + .alg = "ecdsa-nist-p521", + .test = alg_test_akcipher, + .fips_allowed = 1, + .suite = { + .akcipher = __VECS(ecdsa_nist_p521_tv_template) + } + }, { .alg = "ecrdsa", .test = alg_test_akcipher, .suite = { --- linux-xilinx-6.8.0.orig/crypto/testmgr.h +++ linux-xilinx-6.8.0/crypto/testmgr.h @@ -653,6 +653,30 @@ static const struct akcipher_testvec ecdsa_nist_p192_tv_template[] = { { .key = + "\x04\xf7\x46\xf8\x2f\x15\xf6\x22\x8e\xd7\x57\x4f\xcc\xe7\xbb\xc1" + "\xd4\x09\x73\xcf\xea\xd0\x15\x07\x3d\xa5\x8a\x8a\x95\x43\xe4\x68" + "\xea\xc6\x25\xc1\xc1\x01\x25\x4c\x7e\xc3\x3c\xa6\x04\x0a\xe7\x08" + "\x98", + .key_len = 49, + .params = + "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48" + "\xce\x3d\x03\x01\x01", + .param_len = 21, + .m = + "\xcd\xb9\xd2\x1c\xb7\x6f\xcd\x44\xb3\xfd\x63\xea\xa3\x66\x7f\xae" + "\x63\x85\xe7\x82", + .m_size = 20, + .algo = OID_id_ecdsa_with_sha1, + .c = + "\x30\x35\x02\x19\x00\xba\xe5\x93\x83\x6e\xb6\x3b\x63\xa0\x27\x91" + "\xc6\xf6\x7f\xc3\x09\xad\x59\xad\x88\x27\xd6\x92\x6b\x02\x18\x10" + "\x68\x01\x9d\xba\xce\x83\x08\xef\x95\x52\x7b\xa0\x0f\xe4\x18\x86" + "\x80\x6f\xa5\x79\x77\xda\xd0", + .c_size = 55, + .public_key_vec = true, + .siggen_sigver_test = true, + }, { + .key = "\x04\xb6\x4b\xb1\xd1\xac\xba\x24\x8f\x65\xb2\x60\x00\x90\xbf\xbd" "\x78\x05\x73\xe9\x79\x1d\x6f\x7c\x0b\xd2\xc3\x93\xa7\x28\xe1\x75" "\xf7\xd5\x95\x1d\x28\x10\xc0\x75\x50\x5c\x1a\x4f\x3f\x8f\xa5\xee" @@ -756,6 +780,32 @@ static const struct akcipher_testvec ecdsa_nist_p256_tv_template[] = { { .key = + "\x04\xb9\x7b\xbb\xd7\x17\x64\xd2\x7e\xfc\x81\x5d\x87\x06\x83\x41" + "\x22\xd6\x9a\xaa\x87\x17\xec\x4f\x63\x55\x2f\x94\xba\xdd\x83\xe9" + "\x34\x4b\xf3\xe9\x91\x13\x50\xb6\xcb\xca\x62\x08\xe7\x3b\x09\xdc" + "\xc3\x63\x4b\x2d\xb9\x73\x53\xe4\x45\xe6\x7c\xad\xe7\x6b\xb0\xe8" + "\xaf", + .key_len = 65, + .params = + "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48" + "\xce\x3d\x03\x01\x07", + .param_len = 21, + .m = + "\xc2\x2b\x5f\x91\x78\x34\x26\x09\x42\x8d\x6f\x51\xb2\xc5\xaf\x4c" + "\x0b\xde\x6a\x42", + .m_size = 20, + .algo = OID_id_ecdsa_with_sha1, + .c = + "\x30\x46\x02\x21\x00\xf9\x25\xce\x9f\x3a\xa6\x35\x81\xcf\xd4\xe7" + "\xb7\xf0\x82\x56\x41\xf7\xd4\xad\x8d\x94\x5a\x69\x89\xee\xca\x6a" + "\x52\x0e\x48\x4d\xcc\x02\x21\x00\xd7\xe4\xef\x52\x66\xd3\x5b\x9d" + "\x8a\xfa\x54\x93\x29\xa7\x70\x86\xf1\x03\x03\xf3\x3b\xe2\x73\xf7" + "\xfb\x9d\x8b\xde\xd4\x8d\x6f\xad", + .c_size = 72, + .public_key_vec = true, + .siggen_sigver_test = true, + }, { + .key = "\x04\x8b\x6d\xc0\x33\x8e\x2d\x8b\x67\xf5\xeb\xc4\x7f\xa0\xf5\xd9" "\x7b\x03\xa5\x78\x9a\xb5\xea\x14\xe4\x23\xd0\xaf\xd7\x0e\x2e\xa0" "\xc9\x8b\xdb\x95\xf8\xb3\xaf\xac\x00\x2c\x2c\x1f\x7a\xfd\x95\x88" @@ -866,6 +916,36 @@ static const struct akcipher_testvec ecdsa_nist_p384_tv_template[] = { { + .key = /* secp384r1(sha1) */ + "\x04\x89\x25\xf3\x97\x88\xcb\xb0\x78\xc5\x72\x9a\x14\x6e\x7a\xb1" + "\x5a\xa5\x24\xf1\x95\x06\x9e\x28\xfb\xc4\xb9\xbe\x5a\x0d\xd9\x9f" + "\xf3\xd1\x4d\x2d\x07\x99\xbd\xda\xa7\x66\xec\xbb\xea\xba\x79\x42" + "\xc9\x34\x89\x6a\xe7\x0b\xc3\xf2\xfe\x32\x30\xbe\xba\xf9\xdf\x7e" + "\x4b\x6a\x07\x8e\x26\x66\x3f\x1d\xec\xa2\x57\x91\x51\xdd\x17\x0e" + "\x0b\x25\xd6\x80\x5c\x3b\xe6\x1a\x98\x48\x91\x45\x7a\x73\xb0\xc3" + "\xf1", + .key_len = 97, + .params = + "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04" + "\x00\x22", + .param_len = 18, + .m = + "\x12\x55\x28\xf0\x77\xd5\xb6\x21\x71\x32\x48\xcd\x28\xa8\x25\x22" + "\x3a\x69\xc1\x93", + .m_size = 20, + .algo = OID_id_ecdsa_with_sha1, + .c = + "\x30\x66\x02\x31\x00\xf5\x0f\x24\x4c\x07\x93\x6f\x21\x57\x55\x07" + "\x20\x43\x30\xde\xa0\x8d\x26\x8e\xae\x63\x3f\xbc\x20\x3a\xc6\xf1" + "\x32\x3c\xce\x70\x2b\x78\xf1\x4c\x26\xe6\x5b\x86\xcf\xec\x7c\x7e" + "\xd0\x87\xd7\xd7\x6e\x02\x31\x00\xcd\xbb\x7e\x81\x5d\x8f\x63\xc0" + "\x5f\x63\xb1\xbe\x5e\x4c\x0e\xa1\xdf\x28\x8c\x1b\xfa\xf9\x95\x88" + "\x74\xa0\x0f\xbf\xaf\xc3\x36\x76\x4a\xa1\x59\xf1\x1c\xa4\x58\x26" + "\x79\x12\x2a\xb7\xc5\x15\x92\xc5", + .c_size = 104, + .public_key_vec = true, + .siggen_sigver_test = true, + }, { .key = /* secp384r1(sha224) */ "\x04\x69\x6c\xcf\x62\xee\xd0\x0d\xe5\xb5\x2f\x70\x54\xcf\x26\xa0" "\xd9\x98\x8d\x92\x2a\xab\x9b\x11\xcb\x48\x18\xa1\xa9\x0d\xd5\x18" @@ -989,6 +1069,152 @@ .public_key_vec = true, .siggen_sigver_test = true, }, +}; + +static const struct akcipher_testvec ecdsa_nist_p521_tv_template[] = { + { + .key = /* secp521r1(sha224) */ + "\x04\x01\x4f\x43\x18\xb6\xa9\xc9\x5d\x68\xd3\xa9\x42\xf8\x98\xc0" + "\xd2\xd1\xa9\x50\x3b\xe8\xc4\x40\xe6\x11\x78\x88\x4b\xbd\x76\xa7" + "\x9a\xe0\xdd\x31\xa4\x67\x78\x45\x33\x9e\x8c\xd1\xc7\x44\xac\x61" + "\x68\xc8\x04\xe7\x5c\x79\xb1\xf1\x41\x0c\x71\xc0\x53\xa8\xbc\xfb" + "\xf5\xca\xd4\x01\x40\xfd\xa3\x45\xda\x08\xe0\xb4\xcb\x28\x3b\x0a" + "\x02\x35\x5f\x02\x9f\x3f\xcd\xef\x08\x22\x40\x97\x74\x65\xb7\x76" + "\x85\xc7\xc0\x5c\xfb\x81\xe1\xa5\xde\x0c\x4e\x8b\x12\x31\xb6\x47" + "\xed\x37\x0f\x99\x3f\x26\xba\xa3\x8e\xff\x79\x34\x7c\x3a\xfe\x1f" + "\x3b\x83\x82\x2f\x14", + .key_len = 133, + .params = + "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04" + "\x00\x23", + .param_len = 18, + .m = + "\xa2\x3a\x6a\x8c\x7b\x3c\xf2\x51\xf8\xbe\x5f\x4f\x3b\x15\x05\xc4" + "\xb5\xbc\x19\xe7\x21\x85\xe9\x23\x06\x33\x62\xfb", + .m_size = 28, + .algo = OID_id_ecdsa_with_sha224, + .c = + "\x30\x81\x86\x02\x41\x01\xd6\x43\xe7\xff\x42\xb2\xba\x74\x35\xf6" + "\xdc\x6d\x02\x7b\x22\xac\xe2\xef\x07\x92\xee\x60\x94\x06\xf8\x3f" + "\x59\x0f\x74\xf0\x3f\xd8\x18\xc6\x37\x8a\xcb\xa7\xd8\x7d\x98\x85" + "\x29\x88\xff\x0b\x94\x94\x6c\xa6\x9b\x89\x8b\x1e\xfd\x09\x46\x6b" + "\xc7\xaf\x7a\xb9\x19\x0a\x02\x41\x3a\x26\x0d\x55\xcd\x23\x1e\x7d" + "\xa0\x5e\xf9\x88\xf3\xd2\x32\x90\x57\x0f\xf8\x65\x97\x6b\x09\x4d" + "\x22\x26\x0b\x5f\x49\x32\x6b\x91\x99\x30\x90\x0f\x1c\x8f\x78\xd3" + "\x9f\x0e\x64\xcc\xc4\xe8\x43\xd9\x0e\x1c\xad\x22\xda\x82\x00\x35" + "\xa3\x50\xb1\xa5\x98\x92\x2a\xa5\x52", + .c_size = 137, + .public_key_vec = true, + .siggen_sigver_test = true, + }, + { + .key = /* secp521r1(sha256) */ + "\x04\x01\x05\x3a\x6b\x3b\x5a\x0f\xa7\xb9\xb7\x32\x53\x4e\xe2\xae" + "\x0a\x52\xc5\xda\xdd\x5a\x79\x1c\x30\x2d\x33\x07\x79\xd5\x70\x14" + "\x61\x0c\xec\x26\x4d\xd8\x35\x57\x04\x1d\x88\x33\x4d\xce\x05\x36" + "\xa5\xaf\x56\x84\xfa\x0b\x9e\xff\x7b\x30\x4b\x92\x1d\x06\xf8\x81" + "\x24\x1e\x51\x00\x09\x21\x51\xf7\x46\x0a\x77\xdb\xb5\x0c\xe7\x9c" + "\xff\x27\x3c\x02\x71\xd7\x85\x36\xf1\xaa\x11\x59\xd8\xb8\xdc\x09" + "\xdc\x6d\x5a\x6f\x63\x07\x6c\xe1\xe5\x4d\x6e\x0f\x6e\xfb\x7c\x05" + "\x8a\xe9\x53\xa8\xcf\xce\x43\x0e\x82\x20\x86\xbc\x88\x9c\xb7\xe3" + "\xe6\x77\x1e\x1f\x8a", + .key_len = 133, + .params = + "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04" + "\x00\x23", + .param_len = 18, + .m = + "\xcc\x97\x73\x0c\x73\xa2\x53\x2b\xfa\xd7\x83\x1d\x0c\x72\x1b\x39" + "\x80\x71\x8d\xdd\xc5\x9b\xff\x55\x32\x98\x25\xa2\x58\x2e\xb7\x73", + .m_size = 32, + .algo = OID_id_ecdsa_with_sha256, + .c = + "\x30\x81\x88\x02\x42\x00\xcd\xa5\x5f\x57\x52\x27\x78\x3a\xb5\x06" + "\x0f\xfd\x83\xfc\x0e\xd9\xce\x50\x9f\x7d\x1f\xca\x8b\xa8\x2d\x56" + "\x3c\xf6\xf0\xd8\xe1\xb7\x5d\x95\x35\x6f\x02\x0e\xaf\xe1\x4c\xae" + "\xce\x54\x76\x9a\xc2\x8f\xb8\x38\x1f\x46\x0b\x04\x64\x34\x79\xde" + "\x7e\xd7\x59\x10\xe9\xd9\xd5\x02\x42\x01\xcf\x50\x85\x38\xf9\x15" + "\x83\x18\x04\x6b\x35\xae\x65\xb5\x99\x12\x0a\xa9\x79\x24\xb9\x37" + "\x35\xdd\xa0\xe0\x87\x2c\x44\x4b\x5a\xee\xaf\xfa\x10\xdd\x9b\xfb" + "\x36\x1a\x31\x03\x42\x02\x5f\x50\xf0\xa2\x0d\x1c\x57\x56\x8f\x12" + "\xb7\x1d\x91\x55\x38\xb6\xf6\x34\x65\xc7\xbd", + .c_size = 139, + .public_key_vec = true, + .siggen_sigver_test = true, + }, + { + .key = /* secp521r1(sha384) */ + "\x04\x00\x2e\xd6\x21\x04\x75\xc3\xdc\x7d\xff\x0e\xf3\x70\x25\x2b" + "\xad\x72\xfc\x5a\x91\xf1\xd5\x9c\x64\xf3\x1f\x47\x11\x10\x62\x33" + "\xfd\x2e\xe8\x32\xca\x9e\x6f\x0a\x4c\x5b\x35\x9a\x46\xc5\xe7\xd4" + "\x38\xda\xb2\xf0\xf4\x87\xf3\x86\xf4\xea\x70\xad\x1e\xd4\x78\x8c" + "\x36\x18\x17\x00\xa2\xa0\x34\x1b\x2e\x6a\xdf\x06\xd6\x99\x2d\x47" + "\x50\x92\x1a\x8a\x72\x9c\x23\x44\xfa\xa7\xa9\xed\xa6\xef\x26\x14" + "\xb3\x9d\xfe\x5e\xa3\x8c\xd8\x29\xf8\xdf\xad\xa6\xab\xfc\xdd\x46" + "\x22\x6e\xd7\x35\xc7\x23\xb7\x13\xae\xb6\x34\xff\xd7\x80\xe5\x39" + "\xb3\x3b\x5b\x1b\x94", + .key_len = 133, + .params = + "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04" + "\x00\x23", + .param_len = 18, + .m = + "\x36\x98\xd6\x82\xfa\xad\xed\x3c\xb9\x40\xb6\x4d\x9e\xb7\x04\x26" + "\xad\x72\x34\x44\xd2\x81\xb4\x9b\xbe\x01\x04\x7a\xd8\x50\xf8\x59" + "\xba\xad\x23\x85\x6b\x59\xbe\xfb\xf6\x86\xd4\x67\xa8\x43\x28\x76", + .m_size = 48, + .algo = OID_id_ecdsa_with_sha384, + .c = + "\x30\x81\x88\x02\x42\x00\x93\x96\x76\x3c\x27\xea\xaa\x9c\x26\xec" + "\x51\xdc\xe8\x35\x5e\xae\x16\xf2\x4b\x64\x98\xf7\xec\xda\xc7\x7e" + "\x42\x71\x86\x57\x2d\xf1\x7d\xe4\xdf\x9b\x7d\x9e\x47\xca\x33\x32" + "\x76\x06\xd0\xf9\xc0\xe4\xe6\x84\x59\xfd\x1a\xc4\x40\xdd\x43\xb8" + "\x6a\xdd\xfb\xe6\x63\x4e\x28\x02\x42\x00\xff\xc3\x6a\x87\x6e\xb5" + "\x13\x1f\x20\x55\xce\x37\x97\xc9\x05\x51\xe5\xe4\x3c\xbc\x93\x65" + "\x57\x1c\x30\xda\xa7\xcd\x26\x28\x76\x3b\x52\xdf\xc4\xc0\xdb\x54" + "\xdb\x8a\x0d\x6a\xc3\xf3\x7a\xd1\xfa\xe7\xa7\xe5\x5a\x94\x56\xcf" + "\x8f\xb4\x22\xc6\x4f\xab\x2b\x62\xc1\x42\xb1", + .c_size = 139, + .public_key_vec = true, + .siggen_sigver_test = true, + }, + { + .key = /* secp521r1(sha512) */ + "\x04\x00\xc7\x65\xee\x0b\x86\x7d\x8f\x02\xf1\x74\x5b\xb0\x4c\x3f" + "\xa6\x35\x60\x9f\x55\x23\x11\xcc\xdf\xb8\x42\x99\xee\x6c\x96\x6a" + "\x27\xa2\x56\xb2\x2b\x03\xad\x0f\xe7\x97\xde\x09\x5d\xb4\xc5\x5f" + "\xbd\x87\x37\xbf\x5a\x16\x35\x56\x08\xfd\x6f\x06\x1a\x1c\x84\xee" + "\xc3\x64\xb3\x00\x9e\xbd\x6e\x60\x76\xee\x69\xfd\x3a\xb8\xcd\x7e" + "\x91\x68\x53\x57\x44\x13\x2e\x77\x09\x2a\xbe\x48\xbd\x91\xd8\xf6" + "\x21\x16\x53\x99\xd5\xf0\x40\xad\xa6\xf8\x58\x26\xb6\x9a\xf8\x77" + "\xfe\x3a\x05\x1a\xdb\xa9\x0f\xc0\x6c\x76\x30\x8c\xd8\xde\x44\xae" + "\xd0\x17\xdf\x49\x6a", + .key_len = 133, + .params = + "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04" + "\x00\x23", + .param_len = 18, + .m = + "\x5c\xa6\xbc\x79\xb8\xa0\x1e\x11\x83\xf7\xe9\x05\xdf\xba\xf7\x69" + "\x97\x22\x32\xe4\x94\x7c\x65\xbd\x74\xc6\x9a\x8b\xbd\x0d\xdc\xed" + "\xf5\x9c\xeb\xe1\xc5\x68\x40\xf2\xc7\x04\xde\x9e\x0d\x76\xc5\xa3" + "\xf9\x3c\x6c\x98\x08\x31\xbd\x39\xe8\x42\x7f\x80\x39\x6f\xfe\x68", + .m_size = 64, + .algo = OID_id_ecdsa_with_sha512, + .c = + "\x30\x81\x88\x02\x42\x01\x5c\x71\x86\x96\xac\x21\x33\x7e\x4e\xaa" + "\x86\xec\xa8\x05\x03\x52\x56\x63\x0e\x02\xcc\x94\xa9\x05\xb9\xfb" + "\x62\x1e\x42\x03\x6c\x74\x8a\x1f\x12\x3e\xb7\x7e\x51\xff\x7f\x27" + "\x93\xe8\x6c\x49\x7d\x28\xfc\x80\xa6\x13\xfc\xb6\x90\xf7\xbb\x28" + "\xb5\x04\xb0\xb6\x33\x1c\x7e\x02\x42\x01\x70\x43\x52\x1d\xe3\xc6" + "\xbd\x5a\x40\x95\x35\x89\x4f\x41\x5f\x9e\x19\x88\x05\x3e\x43\x39" + "\x01\xbd\xb7\x7a\x76\x37\x51\x47\x49\x98\x12\x71\xd0\xe9\xca\xa7" + "\xc0\xcb\xaa\x00\x55\xbb\x6a\xb4\x73\x00\xd2\x72\x74\x13\x63\x39" + "\xa6\xe5\x25\x46\x1e\x77\x44\x78\xe0\xd1\x04", + .c_size = 139, + .public_key_vec = true, + .siggen_sigver_test = true, + }, }; /* --- linux-xilinx-6.8.0.orig/debian.master/changelog +++ linux-xilinx-6.8.0/debian.master/changelog @@ -0,0 +1,27237 @@ +linux (6.8.0-48.48) noble; urgency=medium + + * noble/linux: 6.8.0-48.48 -proposed tracker (LP: #2082437) + + * [SRU][Noble] Bad EPP defaults cause performance regressions on select Intel + CPUs (LP: #2077470) + - x86/cpu/vfm: Update arch/x86/include/asm/intel-family.h + - cpufreq: intel_pstate: Allow model specific EPPs + - cpufreq: intel_pstate: Update default EPPs for Meteor Lake + - cpufreq: intel_pstate: Switch to new Intel CPU model defines + - cpufreq: intel_pstate: Update Meteor Lake EPPs + - cpufreq: intel_pstate: Use Meteor Lake EPPs for Arrow Lake + - cpufreq: intel_pstate: Update Balance performance EPP for Emerald Rapids + + * power: Enable intel_rapl driver (LP: #2078834) + - powercap: intel_rapl: Add support for ArrowLake-H platform + + * x86/vmware: Add TDX hypercall support (LP: #2077729) + - x86/vmware: Introduce VMware hypercall API + - x86/vmware: Add TDX hypercall support + + * Guest crashes post migration with migrate_misplaced_folio+0x4cc/0x5d0 + (LP: #2076866) + - mm/mempolicy: use numa_node_id() instead of cpu_to_node() + - mm/numa_balancing: allow migrate on protnone reference with + MPOL_PREFERRED_MANY policy + - mm: convert folio_estimated_sharers() to folio_likely_mapped_shared() + - mm: factor out the numa mapping rebuilding into a new helper + - mm: support multi-size THP numa balancing + - mm/migrate: make migrate_misplaced_folio() return 0 on success + - mm/migrate: move NUMA hinting fault folio isolation + checks under PTL + - mm: fix possible OOB in numa_rebuild_large_mapping() + + * Add 'mm: hold PTL from the first PTE while reclaiming a large folio' to fix + L2 Guest hang during LTP Test (LP: #2076147) + - mm: hold PTL from the first PTE while reclaiming a large folio + + * KOP L2 guest fails to boot with 1 core - SMT8 topology (LP: #2070329) + - KVM: PPC: Book3S HV nestedv2: Add DPDES support in helper library for Guest + state buffer + - KVM: PPC: Book3S HV nestedv2: Fix doorbell emulation + + * L2 Guest migration: continuously dumping while running NFS guest migration + (LP: #2076406) + - KVM: PPC: Book3S HV: Fix the set_one_reg for MMCR3 + - KVM: PPC: Book3S HV: Fix the get_one_reg of SDAR + - KVM: PPC: Book3S HV: Add one-reg interface for DEXCR register + - KVM: PPC: Book3S HV nestedv2: Keep nested guest DEXCR in sync + - KVM: PPC: Book3S HV: Add one-reg interface for HASHKEYR register + - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHKEYR in sync + - KVM: PPC: Book3S HV: Add one-reg interface for HASHPKEYR register + - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHPKEYR in sync + + * perf build disables tracepoint support (LP: #2076190) + - [Packaging] perf: reenable libtraceevent + + * Please backport the more restrictive XSAVES deactivation for Zen1/2 arch + (LP: #2077321) + - x86/CPU/AMD: Improve the erratum 1386 workaround + + * Fix alsa scarlett2 driver in 6.8 (LP: #2076402) + - ALSA: scarlett2: Move initialisation code lower in the source + - ALSA: scarlett2: Implement handling of the ACK notification + + * rtw89: reset IDMEM mode to prevent download firmware failure (LP: #2077396) + - wifi: rtw89: 885xb: reset IDMEM mode to prevent download firmware failure + + * CVE-2024-43858 + - jfs: Fix array-index-out-of-bounds in diFree + + * CVE-2024-42280 + - mISDN: Fix a use after free in hfcmulti_tx() + + * CVE-2024-42271 + - net/iucv: fix use after free in iucv_sock_close() + + * [Ubuntu-24.04] FADump with recommended crash size is making the L1 hang + (LP: #2060039) + - powerpc/64s/radix/kfence: map __kfence_pool at page granularity + + * Noble update: upstream stable patchset 2024-09-09 (LP: #2079945) + - ocfs2: add bounds checking to ocfs2_check_dir_entry() + - jfs: don't walk off the end of ealist + - fs/ntfs3: Add a check for attr_names and oatbl + - fs/ntfs3: Validate ff offset + - usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup + - ALSA: hda/realtek: Enable headset mic on Positivo SU C1400 + - ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book Pro 360 + - arm64: dts: qcom: qrb4210-rb2: switch I2C2 to i2c-gpio + - arm64: dts: qcom: msm8996: Disable SS instance in Parkmode for USB + - arm64: dts: qcom: sm6350: Disable SS instance in Parkmode for USB + - arm64: dts: qcom: ipq6018: Disable SS instance in Parkmode for USB + - arm64: dts: qcom: sdm630: Disable SS instance in Parkmode for USB + - ALSA: pcm_dmaengine: Don't synchronize DMA channel when DMA is paused + - ALSA: seq: ump: Skip useless ports for static blocks + - filelock: Fix fcntl/close race recovery compat path + - tun: add missing verification for short frame + - tap: add missing verification for short frame + - s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception() + - ALSA: hda/tas2781: Add new quirk for Lenovo Hera2 Laptop + - arm64: dts: qcom: sc7180: Disable SuperSpeed instances in park mode + - arm64: dts: qcom: sc7280: Disable SuperSpeed instances in park mode + - arm64: dts: qcom: qrb2210-rb1: switch I2C2 to i2c-gpio + - arm64: dts: qcom: msm8998: Disable SS instance in Parkmode for USB + - arm64: dts: qcom: ipq8074: Disable SS instance in Parkmode for USB + - arm64: dts: qcom: sdm845: Disable SS instance in Parkmode for USB + - Upstream stable to v6.6.43, v6.9.12 + + * Noble update: upstream stable patchset 2024-09-02 (LP: #2078304) + - filelock: Remove locks reliably when fcntl/close race is detected + - scsi: core: alua: I/O errors for ALUA state transitions + - scsi: sr: Fix unintentional arithmetic wraparound + - scsi: qedf: Don't process stag work during unload and recovery + - scsi: qedf: Wait for stag work during unload + - scsi: qedf: Set qed_slowpath_params to zero before use + - efi/libstub: zboot.lds: Discard .discard sections + - ACPI: EC: Abort address space access upon error + - ACPI: EC: Avoid returning AE_OK on errors in address space handler + - tools/power/cpupower: Fix Pstate frequency reporting on AMD Family 1Ah CPUs + - wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata + - wifi: mac80211: apply mcast rate only if interface is up + - wifi: mac80211: handle tasklet frames before stopping + - wifi: cfg80211: fix 6 GHz scan request building + - wifi: iwlwifi: mvm: d3: fix WoWLAN command version lookup + - wifi: iwlwifi: mvm: remove stale STA link data during restart + - wifi: iwlwifi: mvm: Handle BIGTK cipher in kek_kck cmd + - wifi: iwlwifi: mvm: handle BA session teardown in RF-kill + - wifi: iwlwifi: mvm: properly set 6 GHz channel direct probe option + - wifi: iwlwifi: mvm: Fix scan abort handling with HW rfkill + - wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan() + - selftests: cachestat: Fix build warnings on ppc64 + - selftests/openat2: Fix build warnings on ppc64 + - selftests/futex: pass _GNU_SOURCE without a value to the compiler + - of/irq: Factor out parsing of interrupt-map parent phandle+args from + of_irq_parse_raw() + - Input: silead - Always support 10 fingers + - net: ipv6: rpl_iptunnel: block BH in rpl_output() and rpl_input() + - ila: block BH in ila_output() + - arm64: armv8_deprecated: Fix warning in isndep cpuhp starting process + - null_blk: fix validation of block size + - kconfig: gconf: give a proper initial state to the Save button + - kconfig: remove wrong expr_trans_bool() + - input: Add event code for accessibility key + - input: Add support for "Do Not Disturb" + - HID: Ignore battery for ELAN touchscreens 2F2C and 4116 + - NFSv4: Fix memory leak in nfs4_set_security_label + - nfs: propagate readlink errors in nfs_symlink_filler + - nfs: Avoid flushing many pages with NFS_FILE_SYNC + - nfs: don't invalidate dentries on transient errors + - cachefiles: add consistency check for copen/cread + - cachefiles: Set object to close if ondemand_id < 0 in copen + - cachefiles: make on-demand read killable + - fs/file: fix the check in find_next_fd() + - mei: demote client disconnect warning on suspend to debug + - iomap: Fix iomap_adjust_read_range for plen calculation + - drm/exynos: dp: drop driver owner initialization + - drm: panel-orientation-quirks: Add quirk for Aya Neo KUN + - drm/mediatek: Call drm_atomic_helper_shutdown() at shutdown time + - nvme: avoid double free special payload + - nvmet: always initialize cqe.result + - ALSA: hda: cs35l56: Fix lifecycle of codec pointer + - wifi: cfg80211: wext: add extra SIOCSIWSCAN data check + - ALSA: hda/realtek: Support Lenovo Thinkbook 16P Gen 5 + - KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group() + - drm/vmwgfx: Fix missing HYPERVISOR_GUEST dependency + - ALSA: hda/realtek: Add more codec ID to no shutup pins list + - spi: Fix OCTAL mode support + - cpumask: limit FORCE_NR_CPUS to just the UP case + - [Config] Remove FORCE_NR_CPUS + - selftests: openvswitch: Set value to nla flags. + - drm/amdgpu: Indicate CU havest info to CP + - ALSA: hda: cs35l56: Select SERIAL_MULTI_INSTANTIATE + - mips: fix compat_sys_lseek syscall + - Input: elantech - fix touchpad state on resume for Lenovo N24 + - Input: i8042 - add Ayaneo Kun to i8042 quirk table + - ASoC: rt722-sdca-sdw: add silence detection register as volatile + - Input: xpad - add support for ASUS ROG RAIKIRI PRO + - ASoC: topology: Fix references to freed memory + - ASoC: topology: Do not assign fields that are already set + - bytcr_rt5640 : inverse jack detect for Archos 101 cesium + - ALSA: dmaengine: Synchronize dma channel after drop() + - ASoC: ti: davinci-mcasp: Set min period size using FIFO config + - ASoC: ti: omap-hdmi: Fix too long driver name + - ASoC: SOF: sof-audio: Skip unprepare for in-use widgets on error rollback + - ASoC: rt722-sdca-sdw: add debounce time for type detection + - nvme: fix NVME_NS_DEAC may incorrectly identifying the disk as EXT_LBA. + - Input: ads7846 - use spi_device_id table + - can: kvaser_usb: fix return value for hif_usb_send_regout + - gpio: pca953x: fix pca953x_irq_bus_sync_unlock race + - octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver + - s390/sclp: Fix sclp_init() cleanup on failure + - platform/mellanox: nvsw-sn2201: Add check for platform_device_add_resources + - platform/x86: wireless-hotkey: Add support for LG Airplane Button + - platform/x86: lg-laptop: Remove LGEX0815 hotkey handling + - platform/x86: lg-laptop: Change ACPI device id + - platform/x86: lg-laptop: Use ACPI device handle when evaluating WMAB/WMBB + - btrfs: qgroup: fix quota root leak after quota disable failure + - ibmvnic: Add tx check to prevent skb leak + - ALSA: PCM: Allow resume only for suspended streams + - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15-gw0xxx + - ALSA: dmaengine_pcm: terminate dmaengine before synchronize + - ASoC: amd: yc: Fix non-functional mic on ASUS M5602RA + - net: usb: qmi_wwan: add Telit FN912 compositions + - net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and + DEV_STATS_ADD() + - powerpc/pseries: Whitelist dtl slub object for copying to userspace + - powerpc/eeh: avoid possible crash when edev->pdev changes + - scsi: libsas: Fix exp-attached device scan after probe failure scanned in + again after probe failed + - tee: optee: ffa: Fix missing-field-initializers warning + - Bluetooth: hci_core: cancel all works upon hci_unregister_dev() + - Bluetooth: btnxpuart: Enable Power Save feature on startup + - bluetooth/l2cap: sync sock recv cb and release + - erofs: ensure m_llen is reset to 0 if metadata is invalid + - drm/amd/display: Add refresh rate range check + - drm/amd/display: Account for cursor prefetch BW in DML1 mode support + - drm/amd/display: Fix refresh rate range for some panel + - drm/radeon: check bo_va->bo is non-NULL before using it + - fs: better handle deep ancestor chains in is_subdir() + - wifi: iwlwifi: properly set WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK + - drivers/perf: riscv: Reset the counter to hpmevent mapping while starting + cpus + - riscv: stacktrace: fix usage of ftrace_graph_ret_addr() + - spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices + - ksmbd: return FILE_DEVICE_DISK instead of super magic + - ASoC: SOF: Intel: hda-pcm: Limit the maximum number of periods by + MAX_BDL_ENTRIES + - selftest/timerns: fix clang build failures for abs() calls + - selftests/vDSO: fix clang build errors and warnings + - hfsplus: fix uninit-value in copy_name + - selftests/bpf: Extend tcx tests to cover late tcx_entry release + - spi: mux: set ctlr->bits_per_word_mask + - ALSA: hda: Use imply for suggesting CONFIG_SERIAL_MULTI_INSTANTIATE + - [Config] Update CONFIG_SERIAL_MULTI_INSTANTIATE + - cifs: fix noisy message on copy_file_range + - Bluetooth: L2CAP: Fix deadlock + - of/irq: Disable "interrupt-map" parsing for PASEMI Nemo + - wifi: cfg80211: wext: set ssids=NULL for passive scans + - wifi: mac80211: disable softirqs for queued frame handling + - wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL + - cachefiles: fix slab-use-after-free in fscache_withdraw_volume() + - cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie() + - btrfs: ensure fast fsync waits for ordered extents after a write failure + - PNP: Hide pnp_bus_type from the non-PNP code + - ACPI: AC: Properly notify powermanagement core about changes + - selftests/overlayfs: Fix build error on ppc64 + - nvme-fabrics: use reserved tag for reg read/write command + - LoongArch: Fix GMAC's phy-mode definitions in dts + - io_uring: fix possible deadlock in io_register_iowq_max_workers() + - vfio: Create vfio_fs_type with inode per device + - vfio/pci: Use unmap_mapping_range() + - parport: amiga: Mark driver struct with __refdata to prevent section + mismatch + - drm: renesas: shmobile: Call drm_atomic_helper_shutdown() at shutdown time + - vfio/pci: Insert full vma on mmap'd MMIO fault + - ALSA: hda: cs35l41: Support Lenovo Thinkbook 16P Gen 5 + - ALSA: hda: cs35l41: Support Lenovo Thinkbook 13x Gen 4 + - ALSA: hda/realtek: Support Lenovo Thinkbook 13x Gen 4 + - wifi: mac80211: Avoid address calculations via out of bounds array indexing + - drm/amd/display: change dram_clock_latency to 34us for dcn35 + - closures: Change BUG_ON() to WARN_ON() + - ASoC: codecs: ES8326: Solve headphone detection issue + - ASoC: Intel: avs: Fix route override + - net: mvpp2: fill-in dev_port attribute + - btrfs: scrub: handle RST lookup error correctly + - clk: qcom: apss-ipq-pll: remove 'config_ctl_hi_val' from Stromer pll configs + - drm/amd/display: Update efficiency bandwidth for dcn351 + - drm/amd/display: Fix array-index-out-of-bounds in dml2/FCLKChangeSupport + - btrfs: fix uninitialized return value in the ref-verify tool + - spi: davinci: Unset POWERDOWN bit when releasing resources + - mm: page_ref: remove folio_try_get_rcu() + - ALSA: hda: cs35l41: Fix swapped l/r audio channels for Lenovo ThinBook 13x + Gen4 + - netfs, fscache: export fscache_put_volume() and add fscache_try_get_volume() + - Upstream stable to v6.6.42, v6.9.11 + + * CVE-2024-27022 + - Revert "Revert "fork: defer linking file vma until vma is fully + initialized"" + + * UBSAN: array-index-out-of-bounds in /build/linux-Z1RxaK/linux- + 6.8.0/drivers/gpu/drm/amd/amdgpu/../pm/powerplay/hwmgr/processpptables.c:124 + 9:61 (LP: #2078041) + - drm/amdgpu/pptable: convert some variable sized arrays to [] style + - drm/amdgpu: convert some variable sized arrays to [] style + - drm/amdgpu/pptable: Fix UBSAN array-index-out-of-bounds + + * alsa: Headphone and Speaker couldn't output sound intermittently + (LP: #2077690) + - ALSA: hda/realtek - Fixed ALC256 headphone no sound + - ALSA: hda/realtek - FIxed ALC285 headphone no sound + + * Fix ethernet performance on JSL and EHL (LP: #2077858) + - intel_idle: Disable promotion to C1E on Jasper Lake and Elkhart Lake + + * Noble update: upstream stable patchset 2024-08-29 (LP: #2078289) + - Revert "usb: xhci: prevent potential failure in handle_tx_event() for + Transfer events without TRB" + - Compiler Attributes: Add __uninitialized macro + - mm: prevent derefencing NULL ptr in pfn_section_valid() + - scsi: ufs: core: Fix ufshcd_clear_cmd racing issue + - scsi: ufs: core: Fix ufshcd_abort_one racing issue + - vfio/pci: Init the count variable in collecting hot-reset devices + - cachefiles: propagate errors from vfs_getxattr() to avoid infinite loop + - cachefiles: stop sending new request when dropping object + - cachefiles: cancel all requests for the object that is being dropped + - cachefiles: wait for ondemand_object_worker to finish when dropping object + - cachefiles: cyclic allocation of msg_id to avoid reuse + - cachefiles: add missing lock protection when polling + - dsa: lan9303: Fix mapping between DSA port number and PHY address + - filelock: fix potential use-after-free in posix_lock_inode + - fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading + - vfs: don't mod negative dentry count when on shrinker list + - net: bcmasp: Fix error code in probe() + - tcp: fix incorrect undo caused by DSACK of TLP retransmit + - bpf: Fix too early release of tcx_entry + - net: phy: microchip: lan87xx: reinit PHY after cable test + - skmsg: Skip zero length skb in sk_msg_recvmsg + - octeontx2-af: Fix incorrect value output on error path in + rvu_check_rsrc_availability() + - net: fix rc7's __skb_datagram_iter() + - i40e: Fix XDP program unloading while removing the driver + - net: ethernet: lantiq_etop: fix double free in detach + - bpf: fix order of args in call to bpf_map_kvcalloc + - bpf: make timer data struct more generic + - bpf: replace bpf_timer_init with a generic helper + - bpf: Fail bpf_timer_cancel when callback is being cancelled + - net: ethernet: mtk-star-emac: set mac_managed_pm when probing + - ppp: reject claimed-as-LCP but actually malformed packets + - ethtool: netlink: do not return SQI value if link is down + - udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). + - net, sunrpc: Remap EPERM in case of connection failure in + xs_tcp_setup_socket + - s390: Mark psw in __load_psw_mask() as __unitialized + - arm64: dts: qcom: sc8180x: Fix LLCC reg property again + - firmware: cs_dsp: Fix overflow checking of wmfw header + - firmware: cs_dsp: Return error if block header overflows file + - firmware: cs_dsp: Validate payload length before processing block + - firmware: cs_dsp: Prevent buffer overrun when processing V2 alg headers + - ASoC: SOF: Intel: hda: fix null deref on system suspend entry + - firmware: cs_dsp: Use strnlen() on name fields in V1 wmfw files + - ARM: davinci: Convert comma to semicolon + - octeontx2-af: replace cpt slot with lf id on reg write + - octeontx2-af: fix a issue with cpt_lf_alloc mailbox + - octeontx2-af: fix detection of IP layer + - octeontx2-af: fix issue with IPv6 ext match for RSS + - octeontx2-af: fix issue with IPv4 match for RSS + - cifs: fix setting SecurityFlags to true + - Revert "sched/fair: Make sure to try to detach at least one movable task" + - tcp: avoid too many retransmit packets + - net: ks8851: Fix deadlock with the SPI chip variant + - net: ks8851: Fix potential TX stall after interface reopen + - USB: serial: option: add Telit generic core-dump composition + - USB: serial: option: add Telit FN912 rmnet compositions + - USB: serial: option: add Fibocom FM350-GL + - USB: serial: option: add support for Foxconn T99W651 + - USB: serial: option: add Netprisma LCUK54 series modules + - USB: serial: option: add Rolling RW350-GL variants + - USB: serial: mos7840: fix crash on resume + - USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k + - usb: dwc3: pci: add support for the Intel Panther Lake + - usb: gadget: configfs: Prevent OOB read/write in usb_string_copy() + - USB: core: Fix duplicate endpoint bug by clearing reserved bits in the + descriptor + - misc: microchip: pci1xxxx: Fix return value of nvmem callbacks + - hpet: Support 32-bit userspace + - xhci: always resume roothubs if xHC was reset during resume + - s390/mm: Add NULL pointer check to crst_table_free() base_crst_free() + - mm: vmalloc: check if a hash-index is in cpu_possible_mask + - mm/filemap: skip to create PMD-sized page cache if needed + - mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray + - ksmbd: discard write access to the directory open + - iio: trigger: Fix condition for own trigger + - arm64: dts: qcom: sa8775p: Correct IRQ number of EL2 non-secure physical + timer + - arm64: dts: qcom: sc8280xp-x13s: fix touchscreen power on + - nvmem: rmem: Fix return value of rmem_read() + - nvmem: meson-efuse: Fix return value of nvmem callbacks + - nvmem: core: only change name to fram for current attribute + - platform/x86: toshiba_acpi: Fix array out-of-bounds access + - tty: serial: ma35d1: Add a NULL check for of_node + - ALSA: hda/realtek: add quirk for Clevo V5[46]0TU + - ALSA: hda/realtek: Enable Mute LED on HP 250 G7 + - ALSA: hda/realtek: Limit mic boost on VAIO PRO PX + - Fix userfaultfd_api to return EINVAL as expected + - pmdomain: qcom: rpmhpd: Skip retention level for Power Domains + - libceph: fix race between delayed_work() and ceph_monc_stop() + - ACPI: processor_idle: Fix invalid comparison with insertion sort for latency + - cpufreq: ACPI: Mark boost policy as enabled when setting boost + - cpufreq: Allow drivers to advertise boost enabled + - wireguard: selftests: use acpi=off instead of -no-acpi for recent QEMU + - wireguard: allowedips: avoid unaligned 64-bit memory accesses + - wireguard: queueing: annotate intentional data race in cpu round robin + - wireguard: send: annotate intentional data race in checking empty queue + - misc: fastrpc: Fix DSP capabilities request + - misc: fastrpc: Avoid updating PD type for capability request + - misc: fastrpc: Copy the complete capability structure to user + - misc: fastrpc: Fix memory leak in audio daemon attach operation + - misc: fastrpc: Fix ownership reassignment of remote heap + - misc: fastrpc: Restrict untrusted app to attach to privileged PD + - mm/shmem: disable PMD-sized page cache if needed + - mm/damon/core: merge regions aggressively when max_nr_regions is unmet + - selftests/net: fix gro.c compilation failure due to non-existent + opt_ipproto_off + - ext4: avoid ptr null pointer dereference + - sched: Move psi_account_irqtime() out of update_rq_clock_task() hotpath + - i2c: rcar: bring hardware to known state when probing + - i2c: mark HostNotify target address as used + - i2c: rcar: ensure Gen3+ reset does not disturb local targets + - i2c: testunit: avoid re-issued work after read message + - i2c: rcar: clear NO_RXDMA flag after resetting + - x86/bhi: Avoid warning in #DB handler due to BHI mitigation + - kbuild: Make ld-version.sh more robust against version string changes + - spi: axi-spi-engine: fix sleep calculation + - minixfs: Fix minixfs_rename with HIGHMEM + - bpf: Defer work in bpf_timer_cancel_and_free + - netfilter: nf_tables: prefer nft_chain_validate + - arm64: dts: qcom: x1e80100-*: Allocate some CMA buffers + - arm64: dts: qcom: sm6115: add iommu for sdhc_1 + - arm64: dts: qcom: qdu1000: Fix LLCC reg property + - net: ethtool: Fix RSS setting + - nilfs2: fix kernel bug on rename operation of broken directory + - cachestat: do not flush stats in recency check + - mm: fix crashes from deferred split racing folio migration + - nvmem: core: limit cell sysfs permissions to main attribute ones + - serial: imx: ensure RTS signal is not left active after shutdown + - mmc: sdhci: Fix max_seg_size for 64KiB PAGE_SIZE + - mmc: davinci_mmc: Prevent transmitted data size from exceeding sgm's length + - mm/readahead: limit page cache size in page_cache_ra_order() + - Revert "dt-bindings: cache: qcom,llcc: correct QDU1000 reg entries" + - sched/deadline: Fix task_struct reference leak + - Upstream stable to v6.6.40, v6.6.41, v6.9.10 + + * [SRU][HPE 24.04] Intel FVL NIC FW flash fails with inbox driver, causing + driver not detected (LP: #2076675) // Noble update: upstream stable patchset + 2024-08-29 (LP: #2078289) + - i40e: fix: remove needless retries of NVM update + + * CVE-2024-41022 + - drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq() + + * Deadlock occurs while suspending md raid (LP: #2073695) + - md: change the return value type of md_write_start to void + - md: fix deadlock between mddev_suspend and flush bio + + * Lenovo X12 Detachable Gen 2 unresponsive under light load (LP: #2076361) + - drm/i915: Enable Wa_16019325821 + - drm/i915/guc: Add support for w/a KLVs + - drm/i915/guc: Enable Wa_14019159160 + + * Regression: unable to reach low idle states on Tiger Lake (LP: #2072679) + - SAUCE: PCI: ASPM: Allow OS to configure ASPM where BIOS is incapable of + - SAUCE: PCI: vmd: Let OS control ASPM for devices under VMD domain + + * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) + - locking/mutex: Introduce devm_mutex_init() + - leds: an30259a: Use devm_mutex_init() for mutex initialization + - crypto: hisilicon/debugfs - Fix debugfs uninit process issue + - drm/lima: fix shared irq handling on driver remove + - powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt. + - media: dvb: as102-fe: Fix as10x_register_addr packing + - media: dvb-usb: dib0700_devices: Add missing release_firmware() + - IB/core: Implement a limit on UMAD receive List + - scsi: qedf: Make qedf_execute_tmf() non-preemptible + - selftests/bpf: adjust dummy_st_ops_success to detect additional error + - selftests/bpf: do not pass NULL for non-nullable params in dummy_st_ops + - selftests/bpf: dummy_st_ops should reject 0 for non-nullable params + - RISC-V: KVM: Fix the initial sample period value + - crypto: aead,cipher - zeroize key buffer after use + - media: mediatek: vcodec: Only free buffer VA that is not NULL + - drm/amdgpu: Fix uninitialized variable warnings + - drm/amdgpu: Initialize timestamp for some legacy SOCs + - drm/amd/display: Check index msg_id before read or write + - drm/amd/display: Check pipe offset before setting vblank + - drm/amd/display: Skip finding free audio for unknown engine_id + - drm/amd/display: Fix uninitialized variables in DM + - drm/amdgpu: fix uninitialized scalar variable warning + - drm/amdgpu: fix the warning about the expression (int)size - len + - media: dw2102: Don't translate i2c read into write + - riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma + - sctp: prefer struct_size over open coded arithmetic + - firmware: dmi: Stop decoding on broken entry + - Input: ff-core - prefer struct_size over open coded arithmetic + - wifi: mt76: replace skb_put with skb_put_zero + - wifi: mt76: mt7996: add sanity checks for background radar trigger + - thermal/drivers/mediatek/lvts_thermal: Check NULL ptr on lvts_data + - media: dvb-frontends: tda18271c2dd: Remove casting during div + - media: s2255: Use refcount_t instead of atomic_t for num_channels + - media: dvb-frontends: tda10048: Fix integer overflow + - i2c: i801: Annotate apanel_addr as __ro_after_init + - powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n + - orangefs: fix out-of-bounds fsid access + - kunit: Fix timeout message + - powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#" + - selftests/net: fix uninitialized variables + - igc: fix a log entry using uninitialized netdev + - bpf: Avoid uninitialized value in BPF_CORE_READ_BITFIELD + - serial: imx: Raise TX trigger level to 8 + - jffs2: Fix potential illegal address access in jffs2_free_inode + - s390/pkey: Wipe sensitive data on failure + - btrfs: scrub: initialize ret in scrub_simple_mirror() to fix compilation + warning + - cdrom: rearrange last_media_change check to avoid unintentional overflow + - tools/power turbostat: Remember global max_die_id + - vhost: Use virtqueue mutex for swapping worker + - vhost: Release worker mutex during flushes + - vhost_task: Handle SIGKILL by flushing work and exiting + - mac802154: fix time calculation in ieee802154_configure_durations() + - net: phy: phy_device: Fix PHY LED blinking code comment + - UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open() + - net/mlx5: E-switch, Create ingress ACL when needed + - net/mlx5e: Add mqprio_rl cleanup and free in mlx5e_priv_cleanup() + - Bluetooth: hci_event: Fix setting of unicast qos interval + - Bluetooth: Ignore too large handle values in BIG + - Bluetooth: ISO: Check socket flag instead of hcon + - bluetooth/hci: disallow setting handle bigger than HCI_CONN_HANDLE_MAX + - KVM: s390: fix LPSWEY handling + - e1000e: Fix S0ix residency on corporate systems + - gpiolib: of: fix lookup quirk for MIPS Lantiq + - net: allow skb_datagram_iter to be called from any context + - net: txgbe: initialize num_q_vectors for MSI/INTx interrupts + - net: ntb_netdev: Move ntb_netdev_rx_handler() to call netif_rx() from + __netif_rx() + - gpio: mmio: do not calculate bgpio_bits via "ngpios" + - wifi: wilc1000: fix ies_len type in connect path + - riscv: kexec: Avoid deadlock in kexec crash path + - netfilter: nf_tables: unconditionally flush pending work before notifier + - bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set() + - selftests: fix OOM in msg_zerocopy selftest + - selftests: make order checking verbose in msg_zerocopy selftest + - inet_diag: Initialize pad field in struct inet_diag_req_v2 + - mlxsw: core_linecards: Fix double memory deallocation in case of invalid INI + file + - gpiolib: of: add polarity quirk for TSC2005 + - cpu: Fix broken cmdline "nosmp" and "maxcpus=0" + - platform/x86: toshiba_acpi: Fix quickstart quirk handling + - Revert "igc: fix a log entry using uninitialized netdev" + - nilfs2: fix inode number range checks + - nilfs2: add missing check for inode numbers on directory entries + - mm: optimize the redundant loop of mm_update_owner_next() + - mm: avoid overflows in dirty throttling logic + - btrfs: fix adding block group to a reclaim list and the unused list during + reclaim + - scsi: mpi3mr: Use proper format specifier in mpi3mr_sas_port_add() + - Bluetooth: hci_bcm4377: Fix msgid release + - Bluetooth: qca: Fix BT enable failure again for QCA6390 after warm reboot + - can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct + - fsnotify: Do not generate events for O_PATH file descriptors + - Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), + again" + - drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes + - drm/amdgpu/atomfirmware: silence UBSAN warning + - drm: panel-orientation-quirks: Add quirk for Valve Galileo + - clk: qcom: gcc-ipq9574: Add BRANCH_HALT_VOTED flag + - clk: sunxi-ng: common: Don't call hw_to_ccu_common on hw without common + - powerpc/pseries: Fix scv instruction crash with kexec + - powerpc/64s: Fix unnecessary copy to 0 when kernel is booted at address 0 + - mtd: rawnand: Ensure ECC configuration is propagated to upper layers + - mtd: rawnand: Fix the nand_read_data_op() early check + - mtd: rawnand: Bypass a couple of sanity checks during NAND identification + - mtd: rawnand: rockchip: ensure NVDDR timings are rejected + - net: stmmac: dwmac-qcom-ethqos: fix error array size + - arm64: dts: rockchip: Fix the DCDC_REG2 minimum voltage on Quartz64 Model B + - media: dw2102: fix a potential buffer overflow + - clk: qcom: gcc-sm6350: Fix gpll6* & gpll7 parents + - clk: qcom: clk-alpha-pll: set ALPHA_EN bit for Stromer Plus PLLs + - clk: mediatek: mt8183: Only enable runtime PM on mt8183-mfgcfg + - i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr + - fs/ntfs3: Mark volume as dirty if xattr is broken + - ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897 + - vhost-scsi: Handle vhost_vq_work_queue failures for events + - nvme-multipath: find NUMA path only for online numa-node + - dma-mapping: benchmark: avoid needless copy_to_user if benchmark fails + - connector: Fix invalid conversion in cn_proc.h + - nvme: adjust multiples of NVME_CTRL_PAGE_SIZE in offset + - regmap-i2c: Subtract reg size from max_write + - platform/x86: touchscreen_dmi: Add info for GlobalSpace SolT IVW 11.6" + tablet + - platform/x86: touchscreen_dmi: Add info for the EZpad 6s Pro + - nvmet: fix a possible leak when destroy a ctrl during qp establishment + - kbuild: fix short log for AS in link-vmlinux.sh + - nfc/nci: Add the inconsistency check between the input data length and count + - spi: cadence: Ensure data lines set to low during dummy-cycle period + - ALSA: ump: Set default protocol when not given explicitly + - drm/amdgpu: silence UBSAN warning + - null_blk: Do not allow runt zone with zone capacity smaller then zone size + - nilfs2: fix incorrect inode allocation from reserved inodes + - leds: mlxreg: Use devm_mutex_init() for mutex initialization + - net: dql: Avoid calling BUG() when WARN() is enough + - drm/xe: Add outer runtime_pm protection to xe_live_ktest@xe_dma_buf + - bpf: mark bpf_dummy_struct_ops.test_1 parameter as nullable + - drm/amdgpu: fix double free err_addr pointer warnings + - drm/amd/display: Fix overlapping copy within dml_core_mode_programming + - drm/amd/display: update pipe topology log to support subvp + - drm/amd/display: Do not return negative stream id for array + - drm/amd/display: ASSERT when failing to find index by plane/stream id + - usb: xhci: prevent potential failure in handle_tx_event() for Transfer + events without TRB + - media: i2c: st-mipid02: Use the correct div function + - media: tc358746: Use the correct div_ function + - crypto: hisilicon/sec2 - fix for register offset + - s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings + - s390/pkey: Wipe copies of clear-key structures on failure + - s390/pkey: Wipe copies of protected- and secure-keys + - wifi: cfg80211: restrict NL80211_ATTR_TXQ_QUANTUM values + - wifi: mac80211: fix BSS_CHANGED_UNSOL_BCAST_PROBE_RESP + - net: txgbe: remove separate irq request for MSI and INTx + - net: txgbe: add extra handle for MSI/INTx into thread irq handle + - net: txgbe: free isb resources at the right time + - btrfs: always do the basic checks for btrfs_qgroup_inherit structure + - net: phy: aquantia: add missing include guards + - drm/fbdev-generic: Fix framebuffer on big endian devices + - net: stmmac: enable HW-accelerated VLAN stripping for gmac4 only + - net: rswitch: Avoid use-after-free in rswitch_poll() + - ice: use proper macro for testing bit + - drm/xe/mcr: Avoid clobbering DSS steering + - tcp: Don't flag tcp_sk(sk)->rx_opt.saw_unknown for TCP AO. + - btrfs: zoned: fix calc_available_free_space() for zoned mode + - btrfs: fix folio refcount in __alloc_dummy_extent_buffer() + - Bluetooth: Add quirk to ignore reserved PHY bits in LE Extended Adv Report + - drm/xe: fix error handling in xe_migrate_update_pgtables + - drm/ttm: Always take the bo delayed cleanup path for imported bos + - fs: don't misleadingly warn during thaw operations + - drm/amdkfd: Let VRAM allocations go to GTT domain on small APUs + - drm/amdgpu: correct hbm field in boot status + - Upstream stable to v6.6.38, v6.6.39, v6.9.9 + + * Panels show garbage or flickering when i915.psr2 enabled (LP: #2069993) + - SAUCE: drm/i915/display/psr: add a psr2 disable quirk table + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x93_0x15 + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8b_0x07 + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x78_0x07 + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8c_0x07 + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0x9a_0xf9 + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x8f_0x15 + - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0xa3_0xc3 + + * Random flickering with Intel i915 (Gen9 GPUs in 6th-8th gen CPUs) on Linux + 6.8 (LP: #2062951) + - SAUCE: iommu/intel: disable DMAR for SKL integrated gfx + + * [SRU][22.04.5]: mpi3mr driver update (LP: #2073583) + - scsi: mpi3mr: HDB allocation and posting for hardware and firmware buffers + - scsi: mpi3mr: Trigger support + - scsi: mpi3mr: Add ioctl support for HDB + - scsi: mpi3mr: Support PCI Error Recovery callback handlers + - scsi: mpi3mr: Prevent PCI writes from driver during PCI error recovery + - scsi: mpi3mr: Driver version update + + * Fix power consumption while using HW accelerated video decode on AMD + platforms (LP: #2073282) + - drm/amdgpu/vcn: identify unified queue in sw init + - drm/amdgpu/vcn: not pause dpg for unified queue + + * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435) + - usb: typec: ucsi: Never send a lone connector change ack + - usb: typec: ucsi: Ack also failed Get Error commands + - Input: ili210x - fix ili251x_read_touch_data() return value + - pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER + - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins + - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins + - pinctrl: rockchip: use dedicated pinctrl type for RK3328 + - pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set + - MIPS: pci: lantiq: restore reset gpio polarity + - ASoC: rockchip: i2s-tdm: Fix trcm mode by setting clock on right mclk + - ASoC: mediatek: mt8183-da7219-max98357: Fix kcontrol name collision + - ASoC: atmel: atmel-classd: Re-add dai_link->platform to fix card init + - workqueue: Increase worker desc's length to 32 + - ASoC: q6apm-lpass-dai: close graph on prepare errors + - bpf: Add missed var_off setting in set_sext32_default_val() + - bpf: Add missed var_off setting in coerce_subreg_to_size_sx() + - s390/pci: Add missing virt_to_phys() for directed DIBV + - ASoC: amd: acp: add a null check for chip_pdev structure + - ASoC: amd: acp: remove i2s configuration check in acp_i2s_probe() + - ASoC: fsl-asoc-card: set priv->pdev before using it + - net: dsa: microchip: fix initial port flush problem + - openvswitch: get related ct labels from its master if it is not confirmed + - mlxsw: spectrum_buffers: Fix memory corruptions on Spectrum-4 systems + - ibmvnic: Free any outstanding tx skbs during scrq reset + - net: phy: micrel: add Microchip KSZ 9477 to the device table + - net: dsa: microchip: use collision based back pressure mode + - ice: Rebuild TC queues on VSI queue reconfiguration + - xdp: Remove WARN() from __xdp_reg_mem_model() + - netfilter: fix undefined reference to 'netfilter_lwtunnel_*' when + CONFIG_SYSCTL=n + - btrfs: use NOFS context when getting inodes during logging and log replay + - Fix race for duplicate reqsk on identical SYN + - ALSA: seq: Fix missing channel at encoding RPN/NRPN MIDI2 messages + - net: dsa: microchip: fix wrong register write when masking interrupt + - sparc: fix old compat_sys_select() + - sparc: fix compat recv/recvfrom syscalls + - parisc: use correct compat recv/recvfrom syscalls + - powerpc: restore some missing spu syscalls + - tcp: fix tcp_rcv_fastopen_synack() to enter TCP_CA_Loss for failed TFO + - ALSA: seq: Fix missing MSB in MIDI2 SPP conversion + - netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data + registers + - net: mana: Fix possible double free in error handling path + - drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep + - vduse: validate block features only with block devices + - vduse: Temporarily fail if control queue feature requested + - x86/fpu: Fix AMD X86_BUG_FXSAVE_LEAK fixup + - mtd: partitions: redboot: Added conversion of operands to a larger type + - wifi: ieee80211: check for NULL in ieee80211_mle_size_ok() + - bpf: Mark bpf prog stack with kmsan_unposion_memory in interpreter mode + - RDMA/restrack: Fix potential invalid address access + - net/iucv: Avoid explicit cpumask var allocation on stack + - net/dpaa2: Avoid explicit cpumask var allocation on stack + - crypto: ecdh - explicitly zeroize private_key + - ALSA: emux: improve patch ioctl data validation + - media: dvbdev: Initialize sbuf + - irqchip/loongson: Select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP for + IRQ_LOONGARCH_CPU + - soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message + - gfs2: Fix NULL pointer dereference in gfs2_log_flush + - drm/radeon/radeon_display: Decrease the size of allocated memory + - nvme: fixup comment for nvme RDMA Provider Type + - drm/panel: simple: Add missing display timing flags for KOE TX26D202VM0BWA + - gpio: davinci: Validate the obtained number of IRQs + - RISC-V: fix vector insn load/store width mask + - drm/amdgpu: Fix pci state save during mode-1 reset + - riscv: stacktrace: convert arch_stack_walk() to noinstr + - gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1) + - randomize_kstack: Remove non-functional per-arch entropy filtering + - x86: stop playing stack games in profile_pc() + - parisc: use generic sys_fanotify_mark implementation + - Revert "MIPS: pci: lantiq: restore reset gpio polarity" + - pinctrl: qcom: spmi-gpio: drop broken pm8008 support + - ocfs2: fix DIO failure due to insufficient transaction credits + - nfs: drop the incorrect assertion in nfs_swap_rw() + - mm: fix incorrect vbq reference in purge_fragmented_block + - mmc: sdhci-pci-o2micro: Convert PCIBIOS_* return codes to errnos + - mmc: sdhci-brcmstb: check R1_STATUS for erase/trim/discard + - mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos + - mmc: sdhci: Do not invert write-protect twice + - mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro() + - iio: xilinx-ams: Don't include ams_ctrl_channels in scan_mask + - counter: ti-eqep: enable clock at probe + - kbuild: doc: Update default INSTALL_MOD_DIR from extra to updates + - kbuild: Fix build target deb-pkg: ln: failed to create hard link + - i2c: testunit: don't erase registers after STOP + - i2c: testunit: discard write requests while old command is running + - ata: libata-core: Fix null pointer dereference on error + - ata,scsi: libata-core: Do not leak memory for ata_port struct members + - iio: adc: ad7266: Fix variable checking bug + - iio: accel: fxls8962af: select IIO_BUFFER & IIO_KFIFO_BUF + - iio: chemical: bme680: Fix pressure value output + - iio: chemical: bme680: Fix calibration data variable + - iio: chemical: bme680: Fix overflows in compensate() functions + - iio: chemical: bme680: Fix sensor data read operation + - net: usb: ax88179_178a: improve link status logs + - usb: gadget: printer: SS+ support + - usb: gadget: printer: fix races against disable + - usb: musb: da8xx: fix a resource leak in probe() + - usb: atm: cxacru: fix endpoint checking in cxacru_bind() + - usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to + avoid deadlock + - usb: gadget: aspeed_udc: fix device address configuration + - usb: typec: ucsi: glink: fix child node release in probe function + - usb: ucsi: stm32: fix command completion handling + - usb: dwc3: core: Add DWC31 version 2.00a controller + - usb: dwc3: core: Workaround for CSR read timeout + - Revert "serial: core: only stop transmit when HW fifo is empty" + - serial: 8250_omap: Implementation of Errata i2310 + - serial: imx: set receiver level before starting uart + - serial: core: introduce uart_port_tx_limited_flags() + - serial: bcm63xx-uart: fix tx after conversion to uart_port_tx_limited() + - tty: mcf: MCF54418 has 10 UARTS + - net: can: j1939: Initialize unused data in j1939_send_one() + - net: can: j1939: recover socket queue on CAN bus error during BAM + transmission + - net: can: j1939: enhanced error handling for tightly received RTS messages + in xtp_rx_rts_session_new + - PCI/MSI: Fix UAF in msi_capability_init + - cpufreq: intel_pstate: Use HWP to initialize ITMT if CPPC is missing + - irqchip/loongson-eiointc: Use early_cpu_to_node() instead of cpu_to_node() + - cpu/hotplug: Fix dynstate assignment in __cpuhp_setup_state_cpuslocked() + - irqchip/loongson-liointc: Set different ISRs for different cores + - kbuild: Install dtb files as 0644 in Makefile.dtbinst + - sh: rework sync_file_range ABI + - btrfs: zoned: fix initial free space detection + - csky, hexagon: fix broken sys_sync_file_range + - hexagon: fix fadvise64_64 calling conventions + - drm/drm_file: Fix pid refcounting race + - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes + - drm/fbdev-dma: Only set smem_start is enable per module option + - drm/amdgpu: avoid using null object of framebuffer + - drm/i915/gt: Fix potential UAF by revoke of fence registers + - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes + - drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is + present + - drm/amdgpu/atomfirmware: fix parsing of vram_info + - batman-adv: Don't accept TT entries for out-of-spec VIDs + - can: mcp251xfd: fix infinite loop when xmit fails + - ata: ahci: Clean up sysfs file on error + - ata: libata-core: Fix double free on error + - ftruncate: pass a signed offset + - syscalls: fix compat_sys_io_pgetevents_time64 usage + - syscalls: fix sys_fanotify_mark prototype + - Revert "cpufreq: amd-pstate: Fix the inconsistency in max frequency units" + - mm/page_alloc: Separate THP PCP into movable and non-movable categories + - arm64: dts: rockchip: Fix SD NAND and eMMC init on rk3308-rock-pi-s + - arm64: dts: rockchip: Rename LED related pinctrl nodes on rk3308-rock-pi-s + - arm64: dts: rockchip: Fix the value of `dlg,jack-det-rate` mismatch on + rk3399-gru + - ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node + - arm64: dts: rockchip: make poweroff(8) work on Radxa ROCK 5A + - arm64: dts: rockchip: fix PMIC interrupt pin on ROCK Pi E + - arm64: dts: rockchip: Add sound-dai-cells for RK3368 + - cxl/region: Move cxl_dpa_to_region() work to the region driver + - cxl/region: Avoid null pointer dereference in region lookup + - cxl/region: check interleave capability + - serial: imx: only set receiver level if it is zero + - serial: 8250_omap: Fix Errata i2310 with RX FIFO level check + - tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset() + - pwm: stm32: Improve precision of calculation in .apply() + - pwm: stm32: Fix for settings using period > UINT32_MAX + - pwm: stm32: Calculate prescaler with a division instead of a loop + - pwm: stm32: Refuse too small period requests + - ASoC: cs42l43: Increase default type detect time and button delay + - ASoC: amd: acp: move chip->flag variable assignment + - bonding: fix incorrect software timestamping report + - mlxsw: pci: Fix driver initialization with Spectrum-4 + - vxlan: Pull inner IP header in vxlan_xmit_one(). + - ASoC: mediatek: mt8195: Add platform entry for ETDM1_OUT_BE dai link + - af_unix: Stop recv(MSG_PEEK) at consumed OOB skb. + - af_unix: Don't stop recv(MSG_DONTWAIT) if consumed OOB skb is at the head. + - af_unix: Don't stop recv() at consumed ex-OOB skb. + - af_unix: Fix wrong ioctl(SIOCATMARK) when consumed OOB skb is at the head. + - bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro() + - bpf: Take return from set_memory_rox() into account with + bpf_jit_binary_lock_ro() + - drm/xe: Fix potential integer overflow in page size calculation + - drm/xe: Add a NULL check in xe_ttm_stolen_mgr_init + - drm/amd/display: correct hostvm flag + - drm/amd/display: Skip pipe if the pipe idx not set properly + - bpf: Add a check for struct bpf_fib_lookup size + - drm/xe/xe_devcoredump: Check NULL before assignments + - iommu/arm-smmu-v3: Do not allow a SVA domain to be set on the wrong PASID + - evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509 + - drm/xe: Check pat.ops before dumping PAT settings + - nvmet: do not return 'reserved' for empty TSAS values + - nvmet: make 'tsas' attribute idempotent for RDMA + - iommu/amd: Fix GT feature enablement again + - gpiolib: cdev: Ignore reconfiguration without direction + - kasan: fix bad call to unpoison_slab_object + - mm/memory: don't require head page for do_set_pmd() + - SUNRPC: Fix backchannel reply, again + - Revert "usb: gadget: u_ether: Re-attach netif device to mirror detachment" + - Revert "usb: gadget: u_ether: Replace netif_stop_queue with + netif_device_detach" + - tty: serial: 8250: Fix port count mismatch with the device + - tty: mxser: Remove __counted_by from mxser_board.ports[] + - nvmet-fc: Remove __counted_by from nvmet_fc_tgt_queue.fod[] + - ata: libata-core: Add ATA_HORKAGE_NOLPM for all Crucial BX SSD1 models + - bcachefs: Fix sb_field_downgrade validation + - bcachefs: Fix sb-downgrade validation + - bcachefs: Fix bch2_sb_downgrade_update() + - bcachefs: Fix setting of downgrade recovery passes/errors + - bcachefs: btree_gc can now handle unknown btrees + - pwm: stm32: Fix calculation of prescaler + - pwm: stm32: Fix error message to not describe the previous error path + - cxl/region: Convert cxl_pmem_region_alloc to scope-based resource management + - cxl/mem: Fix no cxl_nvd during pmem region auto-assembling + - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi 4B + - netfs: Fix netfs_page_mkwrite() to check folio->mapping is valid + - netfs: Fix netfs_page_mkwrite() to flush conflicting data, not wait + - Upstream stable to v6.6.37, v6.9.8 + + * [UBUNTU 22.04] s390/cpum_cf: make crypto counters upward compatible + (LP: #2074380) + - s390/cpum_cf: make crypto counters upward compatible across machine types + + * CVE-2024-45016 + - netem: fix return value if duplicate enqueue fails + + -- Stefan Bader Fri, 27 Sep 2024 14:22:35 +0200 + +linux (6.8.0-45.45) noble; urgency=medium + + * noble/linux: 6.8.0-45.45 -proposed tracker (LP: #2078100) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/s2024.08.05) + + * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435) // + CVE-2024-41009 + - bpf: Fix overrunning reservations in ringbuf + + * CVE-2024-42160 + - f2fs: check validation of fault attrs in f2fs_build_fault_attr() + - f2fs: Add inline to f2fs_build_fault_attr() stub + + * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) // + CVE-2024-42224 + - net: dsa: mv88e6xxx: Correct check for empty list + + * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) // + CVE-2024-42154 + - tcp_metrics: validate source addr length + + * CVE-2024-42228 + - drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc + + * CVE-2024-42159 + - scsi: mpi3mr: Sanitise num_phys + + -- Manuel Diewald Fri, 30 Aug 2024 10:32:37 +0200 + +linux (6.8.0-44.44) noble; urgency=medium + + * noble/linux: 6.8.0-44.44 -proposed tracker (LP: #2076647) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/2024.08.05) + + * Disable PCI_DYNAMIC_OF_NODES in Ubuntu (LP: #2074376) + - [Config] Disable PCI_DYNAMIC_OF_NODES + + * [SRU] Turbostat support for Arrow Lake H (LP: #2074372) + - tools/power turbostat: Enhance ARL/LNL support + - x86/cpu: Add model number for another Intel Arrow Lake mobile processor + - tools/power turbostat: Add ARL-H support + + * Noble update: upstream stable patchset 2024-07-30 (LP: #2075154) + - fs/writeback: bail out if there is no more inodes for IO and queued once + - padata: Disable BH when taking works lock on MT path + - crypto: hisilicon/sec - Fix memory leak for sec resource release + - crypto: hisilicon/qm - Add the err memory release process to qm uninit + - io_uring/sqpoll: work around a potential audit memory leak + - rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment + - rcutorture: Make stall-tasks directly exit when rcutorture tests end + - rcutorture: Fix invalid context warning when enable srcu barrier testing + - block/ioctl: prefer different overflow check + - ssb: Fix potential NULL pointer dereference in ssb_device_uevent() + - selftests/bpf: Prevent client connect before server bind in + test_tc_tunnel.sh + - selftests/bpf: Fix flaky test btf_map_in_map/lookup_update + - batman-adv: bypass empty buckets in batadv_purge_orig_ref() + - wifi: ath9k: work around memset overflow warning + - af_packet: avoid a false positive warning in packet_setsockopt() + - ACPI: x86: Add PNP_UART1_SKIP quirk for Lenovo Blade2 tablets + - drop_monitor: replace spin_lock by raw_spin_lock + - scsi: qedi: Fix crash while reading debugfs attribute + - net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module + - net/sched: fix false lockdep warning on qdisc root lock + - kselftest: arm64: Add a null pointer check + - net: dsa: realtek: keep default LED state in rtl8366rb + - netpoll: Fix race condition in netpoll_owner_active + - wifi: mt76: mt7921s: fix potential hung tasks during chip recovery + - HID: Add quirk for Logitech Casa touchpad + - HID: asus: fix more n-key report descriptors if n-key quirked + - ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7 + - Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl + - drm/amd/display: Exit idle optimizations before HDCP execution + - platform/x86: toshiba_acpi: Add quirk for buttons on Z830 + - ASoC: Intel: sof_sdw: add JD2 quirk for HP Omen 14 + - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F + - drm/lima: add mask irq callback to gp and pp + - drm/lima: mask irqs in timeout path before hard reset + - ALSA: hda/realtek: Add quirks for Lenovo 13X + - powerpc/pseries: Enforce hcall result buffer validity and size + - media: intel/ipu6: Fix build with !ACPI + - media: mtk-vcodec: potential null pointer deference in SCP + - powerpc/io: Avoid clang null pointer arithmetic warnings + - platform/x86: p2sb: Don't init until unassigned resources have been assigned + - power: supply: cros_usbpd: provide ID table for avoiding fallback match + - iommu/arm-smmu-v3: Free MSIs in case of ENOMEM + - ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super() + - kprobe/ftrace: bail out if ftrace was killed + - usb: gadget: uvc: configfs: ensure guid to be valid before set + - f2fs: remove clear SB_INLINECRYPT flag in default_options + - usb: misc: uss720: check for incompatible versions of the Belkin F5U002 + - Avoid hw_desc array overrun in dw-axi-dmac + - usb: dwc3: pci: Don't set "linux,phy_charger_detect" property on Lenovo Yoga + Tab2 1380 + - usb: typec: ucsi_glink: drop special handling for CCI_BUSY + - udf: udftime: prevent overflow in udf_disk_stamp_to_time() + - PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports + - f2fs: don't set RO when shutting down f2fs + - MIPS: Octeon: Add PCIe link status check + - serial: imx: Introduce timeout when waiting on transmitter empty + - serial: exar: adding missing CTI and Exar PCI ids + - usb: gadget: function: Remove usage of the deprecated ida_simple_xx() API + - tty: add the option to have a tty reject a new ldisc + - vfio/pci: Collect hot-reset devices to local buffer + - cpufreq: amd-pstate: fix memory leak on CPU EPP exit + - ACPI: EC: Install address space handler at the namespace root + - PCI: Do not wait for disconnected devices when resuming + - ALSA: hda: cs35l41: Possible null pointer dereference in + cs35l41_hda_unbind() + - ALSA: seq: ump: Fix missing System Reset message handling + - MIPS: Routerboard 532: Fix vendor retry check code + - mips: bmips: BCM6358: make sure CBR is correctly set + - tracing: Build event generation tests only as modules + - ALSA: hda/realtek: Remove Framework Laptop 16 from quirks + - ALSA/hda: intel-dsp-config: Document AVS as dsp_driver option + - ice: avoid IRQ collision to fix init failure on ACPI S3 resume + - btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes + - net: mvpp2: use slab_build_skb for oversized frames + - cipso: fix total option length computation + - ALSA: hda: cs35l56: Component should be unbound before deconstruction + - ALSA: hda: tas2781: Component should be unbound before deconstruction + - bpf: Avoid splat in pskb_pull_reason + - ALSA: hda/realtek: Enable headset mic on IdeaPad 330-17IKB 81DM + - netrom: Fix a memory leak in nr_heartbeat_expiry() + - ipv6: prevent possible NULL deref in fib6_nh_init() + - ipv6: prevent possible NULL dereference in rt6_probe() + - xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr() + - netns: Make get_net_ns() handle zero refcount net + - qca_spi: Make interrupt remembering atomic + - net: lan743x: disable WOL upon resume to restore full data path operation + - net: lan743x: Support WOL at both the PHY and MAC appropriately + - net: phy: mxl-gpy: Remove interrupt mask clearing from config_init + - net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc() + - tipc: force a dst refcount before doing decryption + - sched: act_ct: add netns into the key of tcf_ct_flow_table + - ptp: fix integer overflow in max_vclocks_store + - selftests: openvswitch: Use bash as interpreter + - net: stmmac: No need to calculate speed divider when offload is disabled + - virtio_net: checksum offloading handling fix + - virtio_net: fixing XDP for fully checksummed packets handling + - octeontx2-pf: Add error handling to VLAN unoffload handling + - octeontx2-pf: Fix linking objects into multiple modules + - netfilter: ipset: Fix suspicious rcu_dereference_protected() + - seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6 + behaviors + - netfilter: move the sysctl nf_hooks_lwtunnel into the netfilter core + - ice: Fix VSI list rule with ICE_SW_LKUP_LAST type + - bnxt_en: Restore PTP tx_avail count in case of skb_pad() error + - net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings + - RDMA/bnxt_re: Fix the max msix vectors macro + - spi: cs42l43: Correct SPI root clock speed + - RDMA/rxe: Fix responder length checking for UD request packets + - regulator: core: Fix modpost error "regulator_get_regmap" undefined + - dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list + - dmaengine: ioatdma: Fix leaking on version mismatch + - dmaengine: ioatdma: Fix error path in ioat3_dma_probe() + - dmaengine: ioatdma: Fix kmemleak in ioat_pci_probe() + - dmaengine: fsl-edma: avoid linking both modules + - dmaengine: ioatdma: Fix missing kmem_cache_destroy() + - regulator: bd71815: fix ramp values + - thermal/drivers/mediatek/lvts_thermal: Return error in case of invalid efuse + data + - arm64: dts: imx8mp: Fix TC9595 input clock on DH i.MX8M Plus DHCOM SoM + - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix BT shutdown GPIO + - arm64: dts: imx93-11x11-evk: Remove the 'no-sdio' property + - arm64: dts: freescale: imx8mm-verdin: enable hysteresis on slow input pin + - ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is + fine." + - spi: spi-imx: imx51: revert burst length calculation back to bits_per_word + - io_uring/rsrc: fix incorrect assignment of iter->nr_segs in io_import_fixed + - firmware: psci: Fix return value from psci_system_suspend() + - RDMA/mlx5: Fix unwind flow as part of mlx5_ib_stage_init_init + - RDMA/mlx5: Add check for srq max_sge attribute + - RDMA/mana_ib: Ignore optional access flags for MRs + - ACPI: EC: Evaluate orphan _REG under EC device + - arm64: defconfig: enable the vf610 gpio driver + - ext4: avoid overflow when setting values via sysfs + - ext4: fix slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists() + - net: stmmac: Assign configured channel value to EXTTS event + - net: usb: ax88179_178a: improve reset check + - net: do not leave a dangling sk pointer, when socket creation fails + - btrfs: retry block group reclaim without infinite loop + - scsi: ufs: core: Free memory allocated for model before reinit + - cifs: fix typo in module parameter enable_gcm_256 + - LoongArch: Fix watchpoint setting error + - LoongArch: Trigger user-space watchpoints correctly + - LoongArch: Fix multiple hardware watchpoint issues + - KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin() + - KVM: arm64: Disassociate vcpus from redistributor region on teardown + - KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes + - RDMA/rxe: Fix data copy for IB_SEND_INLINE + - RDMA/mlx5: Remove extra unlock on error path + - RDMA/mlx5: Follow rb_key.ats when creating new mkeys + - ovl: fix encoding fid for lower only root + - ALSA: hda/realtek: Limit mic boost on N14AP7 + - ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14AHP9 + - drm/i915/mso: using joiner is not possible with eDP MSO + - drm/radeon: fix UBSAN warning in kv_dpm.c + - drm/amdgpu: fix UBSAN warning in kv_dpm.c + - dt-bindings: dma: fsl-edma: fix dma-channels constraints + - ocfs2: fix NULL pointer dereference in ocfs2_journal_dirty() + - ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger() + - gcov: add support for GCC 14 + - kcov: don't lose track of remote references during softirqs + - efi/x86: Free EFI memory map only when installing a new one. + - serial: 8250_dw: Revert "Move definitions to the shared header" + - mm: mmap: allow for the maximum number of bits for randomizing mmap_base by + default + - tcp: clear tp->retrans_stamp in tcp_rcv_fastopen_synack() + - mm/page_table_check: fix crash on ZONE_DEVICE + - i2c: ocores: set IACK bit after core is enabled + - dt-bindings: i2c: atmel,at91sam: correct path to i2c-controller schema + - dt-bindings: i2c: google,cros-ec-i2c-tunnel: correct path to i2c-controller + schema + - spi: stm32: qspi: Fix dual flash mode sanity test in stm32_qspi_setup() + - arm64: dts: imx8qm-mek: fix gpio number for reg_usdhc2_vmmc + - spi: stm32: qspi: Clamp stm32_qspi_get_mode() output to CCR_BUSWIDTH_4 + - perf: script: add raw|disasm arguments to --insn-trace option + - nbd: Improve the documentation of the locking assumptions + - nbd: Fix signal handling + - tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test + - x86/cpu/vfm: Add new macros to work with (vendor/family/model) values + - x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL + - drm/amd/display: revert Exit idle optimizations before HDCP execution + - ASoC: Intel: sof-sdw: really remove FOUR_SPEAKER quirk + - net/sched: unregister lockdep keys in qdisc_create/qdisc_alloc error path + - kprobe/ftrace: fix build error due to bad function definition + - hid: asus: asus_report_fixup: fix potential read out of bounds + - Revert "mm: mmap: allow for the maximum number of bits for randomizing + mmap_base by default" + - platform/chrome: cros_usbpd_logger: provide ID table for avoiding fallback + match + - platform/chrome: cros_usbpd_notify: provide ID table for avoiding fallback + match + - ubsan: Avoid i386 UBSAN handler crashes with Clang + - arm64: defconfig: select INTERCONNECT_QCOM_SM6115 as built-in + - bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie. + - devlink: use kvzalloc() to allocate devlink instance resources + - wifi: rtw89: 8852c: add quirk to set PCI BER for certain platforms + - clocksource: Make watchdog and suspend-timing multiplication overflow safe + - ACPI: resource: Do IRQ override on GMxBGxx (XMG APEX 17 M23) + - wifi: ath12k: add string type to search board data in board-2.bin for + WCN7850 + - wifi: ath12k: add firmware-2.bin support + - wifi: ath12k: fix kernel crash during resume + - arm64/sysreg: Update PIE permission encodings + - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MV + - wifi: ath12k: fix the problem that down grade phy mode operation + - bpf: avoid uninitialized warnings in verifier_global_subprogs.c + - selftests: net: fix timestamp not arriving in cmsg_time.sh + - net: ena: Add validation for completion descriptors consistency + - drm/amd/display: Workaround register access in idle race with cursor + - cgroup/cpuset: Make cpuset hotplug processing synchronous + - platform/x86: x86-android-tablets: Unregister devices in reverse order + - platform/x86: x86-android-tablets: Add Lenovo Yoga Tablet 2 Pro 1380F/L data + - ALSA: hda/realtek: Add quirks for HP Omen models using CS35L41 + - ext4: fold quota accounting into ext4_xattr_inode_lookup_create() + - ext4: do not create EA inode under buffer lock + - f2fs: fix to detect inconsistent nat entry during truncation + - usb: typec: ucsi_glink: rework quirks implementation + - xhci: remove XHCI_TRUST_TX_LENGTH quirk + - clk: Add a devm variant of clk_rate_exclusive_get() + - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get() + - i2c: lpi2c: Avoid calling clk_get_rate during transfer + - cxl: Add post-reset warning if reset results in loss of previously committed + HDM decoders + - OPP: Fix required_opp_tables for multiple genpds using same table + - wifi: iwlwifi: mvm: fix ROC version check + - wifi: mac80211: Recalc offload when monitor stop + - ice: fix 200G link speed message log + - ice: implement AQ download pkg retry + - bpf: Fix reg_set_min_max corruption of fake_reg + - ALSA: hda: cs35l41: Component should be unbound before deconstruction + - netdev-genl: fix error codes when outputting XDP features + - arm64: dts: freescale: imx8mm-verdin: Fix GPU speed + - phy: qcom-qmp: qserdes-txrx: Add missing registers offsets + - phy: qcom-qmp: pcs: Add missing v6 N4 register offsets + - phy: qcom: qmp-combo: Switch from V6 to V6 N4 register offsets + - powerpc/crypto: Add generated P8 asm to .gitignore + - spi: Exctract spi_dev_check_cs() helper + - spi: Fix SPI slave probe failure + - net: phy: dp83tg720: wake up PHYs in managed mode + - net: phy: dp83tg720: get master/slave configuration in link down state + - RDMA/mlx5: Ensure created mkeys always have a populated rb_key + - drm/amdgpu: fix locking scope when flushing tlb + - drm/amd/display: Remove redundant idle optimization check + - drm/amd/display: Attempt to avoid empty TUs when endpoint is DPIA + - ata: ahci: Do not enable LPM if no LPM states are supported by the HBA + - dmaengine: xilinx: xdma: Fix data synchronisation in xdma_channel_isr() + - net/tcp_ao: Don't leak ao_info on error-path + - mm: shmem: fix getting incorrect lruvec when replacing a shmem folio + - selftests: mptcp: print_test out of verify_listener_events + - selftests: mptcp: userspace_pm: fixed subtest names + - ima: Avoid blocking in RCU read-side critical section + - virt: guest_memfd: fix reference leak on hwpoisoned page + - thermal: int340x: processor_thermal: Support shared interrupts + - thermal: core: Change PM notifier priority to the minimum + - wifi: ath12k: check M3 buffer size as well whey trying to reuse it + - Upstream stable to v6.6.36, v6.9.7 + + * [SRU] Add Dynamic Tuning Technology (DTT) support for Lunar Lake + (LP: #2073961) + - thermal: int340x: processor_thermal: Add Lunar Lake-M PCI ID + + * Kubuntu 24.04 freezes after plugging in ethernet cable (LP: #2073358) + - e1000e: move force SMBUS near the end of enable_ulp function + - e1000e: fix force smbus during suspend flow + + * Noble update: upstream stable patchset 2024-07-25 (LP: #2074091) + - wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects + - wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() + - wifi: cfg80211: fully move wiphy work to unbound workqueue + - wifi: cfg80211: Lock wiphy in cfg80211_get_station + - wifi: cfg80211: pmsr: use correct nla_get_uX functions + - wifi: iwlwifi: mvm: don't initialize csa_work twice + - wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64 + - wifi: iwlwifi: mvm: set properly mac header + - wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef + - wifi: iwlwifi: mvm: check n_ssids before accessing the ssids + - wifi: iwlwifi: mvm: don't read past the mfuart notifcation + - wifi: mac80211: correctly parse Spatial Reuse Parameter Set element + - scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort() + - RISC-V: KVM: No need to use mask when hart-index-bit is 0 + - RISC-V: KVM: Fix incorrect reg_subtype labels in + kvm_riscv_vcpu_set_reg_isa_ext function + - ax25: Fix refcount imbalance on inbound connections + - ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put() + - net/ncsi: Fix the multi thread manner of NCSI driver + - net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume + - bpf: Fix a potential use-after-free in bpf_link_free() + - KVM: SEV-ES: Disallow SEV-ES guests when X86_FEATURE_LBRV is absent + - KVM: SEV-ES: Delegate LBR virtualization to the processor + - vmxnet3: disable rx data ring on dma allocation failure + - ipv6: ioam: block BH from ioam6_output() + - ipv6: sr: block BH in seg6_output_core() and seg6_input_core() + - net: tls: fix marking packets as decrypted + - bpf: Set run context for rawtp test_run callback + - octeontx2-af: Always allocate PF entries from low prioriy zone + - net/smc: avoid overwriting when adjusting sock bufsizes + - net: phy: Micrel KSZ8061: fix errata solution not taking effect problem + - net: sched: sch_multiq: fix possible OOB write in multiq_tune() + - vxlan: Fix regression when dropping packets due to invalid src addresses + - tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB + - mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB + - net/mlx5: Stop waiting for PCI if pci channel is offline + - net/mlx5: Always stop health timer during driver removal + - net/mlx5: Fix tainted pointer delete is case of flow rules creation fail + - net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP + - ptp: Fix error message on failed pin verification + - ice: fix iteration of TLVs in Preserved Fields Area + - ice: remove af_xdp_zc_qps bitmap + - ice: add flag to distinguish reset from .ndo_bpf in XDP rings config + - net: wwan: iosm: Fix tainted pointer delete is case of region creation fail + - af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted + peer. + - af_unix: Annodate data-races around sk->sk_state for writers. + - af_unix: Annotate data-race of sk->sk_state in unix_inq_len(). + - af_unix: Annotate data-races around sk->sk_state in unix_write_space() and + poll(). + - af_unix: Annotate data-race of sk->sk_state in unix_stream_connect(). + - af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg(). + - af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb(). + - af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG. + - af_unix: Annotate data-races around sk->sk_sndbuf. + - af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen. + - af_unix: Use unix_recvq_full_lockless() in unix_stream_connect(). + - af_unix: Use skb_queue_empty_lockless() in unix_release_sock(). + - af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen(). + - af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill(). + - ipv6: fix possible race in __fib6_drop_pcpu_from() + - net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool() + - selftests/mm: log a consistent test name for check_compaction + - irqchip/riscv-intc: Allow large non-standard interrupt number + - irqchip/riscv-intc: Introduce Andes hart-level interrupt controller + - eventfs: Update all the eventfs_inodes from the events descriptor + - io_uring/rsrc: don't lock while !TASK_RUNNING + - io_uring: check for non-NULL file pointer in io_file_can_poll() + - USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages + - USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected + - usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps + - usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state + - mei: me: release irq in mei_me_pci_resume error path + - tty: n_tty: Fix buffer offsets when lookahead is used + - serial: port: Don't block system suspend even if bytes are left to xmit + - landlock: Fix d_parent walk + - jfs: xattr: fix buffer overflow for invalid xattr + - xhci: Set correct transferred length for cancelled bulk transfers + - xhci: Apply reset resume quirk to Etron EJ188 xHCI host + - xhci: Handle TD clearing for multiple streams case + - xhci: Apply broken streams quirk to Etron EJ188 xHCI host + - thunderbolt: debugfs: Fix margin debugfs node creation condition + - scsi: core: Disable CDL by default + - scsi: mpi3mr: Fix ATA NCQ priority support + - scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory + - scsi: sd: Use READ(16) when reading block zero on large capacity disks + - gve: Clear napi->skb before dev_kfree_skb_any() + - powerpc/uaccess: Fix build errors seen with GCC 13/14 + - HID: nvidia-shield: Add missing check for input_ff_create_memless + - cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c + - cxl/region: Fix memregion leaks in devm_cxl_add_region() + - cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd + - cachefiles: remove requests from xarray during flushing requests + - cachefiles: add spin_lock for cachefiles_ondemand_info + - cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd() + - cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read() + - cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read() + - cachefiles: never get a new anonymous fd if ondemand_id is valid + - cachefiles: defer exposing anon_fd until after copy_to_user() succeeds + - cachefiles: flush all requests after setting CACHEFILES_DEAD + - selftests/ftrace: Fix to check required event file + - clk: sifive: Do not register clkdevs for PRCI clocks + - NFSv4.1 enforce rootpath check in fs_location query + - SUNRPC: return proper error from gss_wrap_req_priv + - NFS: add barriers when testing for NFS_FSDATA_BLOCKED + - selftests/tracing: Fix event filter test to retry up to 10 times + - nvme: fix nvme_pr_* status code parsing + - drm/panel: sitronix-st7789v: Add check for of_drm_get_panel_orientation + - platform/x86: dell-smbios: Fix wrong token data in sysfs + - gpio: tqmx86: fix typo in Kconfig label + - gpio: tqmx86: introduce shadow register for GPIO output value + - gpio: tqmx86: store IRQ trigger type and unmask status separately + - gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type + - HID: core: remove unnecessary WARN_ON() in implement() + - iommu/amd: Fix sysfs leak in iommu init + - iommu: Return right value in iommu_sva_bind_device() + - io_uring/io-wq: Use set_bit() and test_bit() at worker->flags + - io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue() + - HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode() + - drm/vmwgfx: Refactor drm connector probing for display modes + - drm/vmwgfx: Filter modes which exceed graphics memory + - drm/vmwgfx: 3D disabled should not effect STDU memory limits + - drm/vmwgfx: Remove STDU logic from generic mode_valid function + - drm/vmwgfx: Don't memcmp equivalent pointers + - af_unix: Annotate data-race of sk->sk_state in unix_accept(). + - modpost: do not warn about missing MODULE_DESCRIPTION() for vmlinux.o + - net: sfp: Always call `sfp_sm_mod_remove()` on remove + - net: hns3: fix kernel crash problem in concurrent scenario + - net: hns3: add cond_resched() to hns3 ring buffer init process + - liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet + - net: stmmac: dwmac-qcom-ethqos: Configure host DMA width + - drm/komeda: check for error-valued pointer + - drm/bridge/panel: Fix runtime warning on panel bridge release + - tcp: fix race in tcp_v6_syn_recv_sock() + - net dsa: qca8k: fix usages of device_get_named_child_node() + - geneve: Fix incorrect inner network header offset when innerprotoinherit is + set + - net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN) + packets + - Bluetooth: fix connection setup in l2cap_connect + - netfilter: nft_inner: validate mandatory meta and payload + - netfilter: ipset: Fix race between namespace cleanup and gc in the list:set + type + - x86/asm: Use %c/%n instead of %P operand modifier in asm templates + - x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking + - scsi: ufs: core: Quiesce request queues before checking pending cmds + - net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP + - gve: ignore nonrelevant GSO type bits when processing TSO headers + - net: stmmac: replace priv->speed with the portTransmitRate from the tc-cbs + parameters + - block: sed-opal: avoid possible wrong address reference in + read_sed_opal_key() + - block: fix request.queuelist usage in flush + - nvmet-passthru: propagate status from id override functions + - net/ipv6: Fix the RT cache flush via sysctl using a previous delay + - net: bridge: mst: pass vlan group directly to br_mst_vlan_set_state + - net: bridge: mst: fix suspicious rcu usage in br_mst_set_state + - ionic: fix use after netif_napi_del() + - af_unix: Read with MSG_PEEK loops if the first unread byte is OOB + - bnxt_en: Adjust logging of firmware messages in case of released token in + __hwrm_send() + - misc: microchip: pci1xxxx: fix double free in the error handling of + gp_aux_bus_probe() + - ksmbd: move leading slash check to smb2_get_name() + - ksmbd: fix missing use of get_write in in smb2_set_ea() + - x86/boot: Don't add the EFI stub to targets, again + - iio: adc: ad9467: fix scan type sign + - iio: dac: ad5592r: fix temperature channel scaling value + - iio: invensense: fix odr switching to same value + - iio: imu: inv_icm42600: delete unneeded update watermark call + - drivers: core: synchronize really_probe() and dev_uevent() + - parisc: Try to fix random segmentation faults in package builds + - ACPI: x86: Force StorageD3Enable on more products + - drm/exynos/vidi: fix memory leak in .get_modes() + - drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found + - mptcp: ensure snd_una is properly initialized on connect + - mptcp: pm: inc RmAddr MIB counter once per RM_ADDR ID + - mptcp: pm: update add_addr counters after connect + - clkdev: Update clkdev id usage to allow for longer names + - irqchip/gic-v3-its: Fix potential race condition in its_vlpi_prop_update() + - x86/kexec: Fix bug with call depth tracking + - x86/amd_nb: Check for invalid SMN reads + - perf/core: Fix missing wakeup when waiting for context reference + - perf auxtrace: Fix multiple use of --itrace option + - riscv: fix overlap of allocated page and PTR_ERR + - tracing/selftests: Fix kprobe event name test for .isra. functions + - kheaders: explicitly define file modes for archived headers + - null_blk: Print correct max open zones limit in null_init_zoned_dev() + - sock_map: avoid race between sock_map_close and sk_psock_put + - dma-buf: handle testing kthreads creation failure + - vmci: prevent speculation leaks by sanitizing event in event_deliver() + - spmi: hisi-spmi-controller: Do not override device identifier + - knfsd: LOOKUP can return an illegal error value + - fs/proc: fix softlockup in __read_vmcore + - ocfs2: use coarse time for new created files + - ocfs2: fix races between hole punching and AIO+DIO + - PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id + - dmaengine: axi-dmac: fix possible race in remove() + - remoteproc: k3-r5: Wait for core0 power-up before powering up core1 + - remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs + - iio: adc: axi-adc: make sure AXI clock is enabled + - iio: invensense: fix interrupt timestamp alignment + - riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context + - rtla/timerlat: Simplify "no value" printing on top + - rtla/auto-analysis: Replace \t with spaces + - drm/i915/gt: Disarm breadcrumbs if engines are already idle + - drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE) + - drm/i915/dpt: Make DPT object unshrinkable + - drm/i915: Fix audio component initialization + - intel_th: pci: Add Meteor Lake-S support + - pmdomain: ti-sci: Fix duplicate PD referrals + - btrfs: zoned: fix use-after-free due to race with dev replace + - xfs: fix imprecise logic in xchk_btree_check_block_owner + - xfs: fix scrub stats file permissions + - xfs: fix SEEK_HOLE/DATA for regions with active COW extents + - xfs: shrink failure needs to hold AGI buffer + - xfs: ensure submit buffers on LSN boundaries in error handlers + - xfs: allow sunit mount option to repair bad primary sb stripe values + - xfs: don't use current->journal_info + - xfs: allow cross-linking special files without project quota + - swiotlb: Enforce page alignment in swiotlb_alloc() + - swiotlb: Reinstate page-alignment for mappings >= PAGE_SIZE + - swiotlb: extend buffer pre-padding to alloc_align_mask if necessary + - tick/nohz_full: Don't abuse smp_call_function_single() in + tick_setup_device() + - mm/huge_memory: don't unpoison huge_zero_folio + - serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level + - Revert "fork: defer linking file vma until vma is fully initialized" + - remoteproc: k3-r5: Jump to error handling labels in start/stop errors + - greybus: Fix use-after-free bug in gb_interface_release due to race + condition. + - ima: Fix use-after-free on a dentry's dname.name + - serial: core: Add UPIO_UNKNOWN constant for unknown port type + - serial: port: Introduce a common helper to read properties + - serial: 8250_dw: Switch to use uart_read_port_properties() + - serial: 8250_dw: Replace ACPI device check by a quirk + - serial: 8250_dw: Don't use struct dw8250_data outside of 8250_dw + - usb-storage: alauda: Check whether the media is initialized + - misc: microchip: pci1xxxx: Fix a memory leak in the error handling of + gp_aux_bus_probe() + - i2c: at91: Fix the functionality flags of the slave-only interface + - i2c: designware: Fix the functionality flags of the slave-only interface + - zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING + - wifi: ath11k: fix WCN6750 firmware crash caused by 17 num_vdevs + - cpufreq: amd-pstate: Unify computation of + {max,min,nominal,lowest_nonlinear}_freq + - cpufreq: amd-pstate: Add quirk for the pstate CPPC capabilities missing + - cpufreq: amd-pstate: remove global header file + - virtio_net: fix possible dim status unrecoverable + - net: ethernet: mtk_eth_soc: handle dma buffer size soc specific + - ice: fix reads from NVM Shadow RAM on E830 and E825-C devices + - ice: map XDP queues to vectors in ice_vsi_map_rings_to_vectors() + - x86/cpu: Get rid of an unnecessary local variable in get_cpu_address_sizes() + - x86/cpu: Provide default cache line size if not enumerated + - selftests/mm: ksft_exit functions do not return + - selftests/mm: compaction_test: fix bogus test success and reduce probability + of OOM-killer invocation + - .editorconfig: remove trim_trailing_whitespace option + - kcov, usb: disable interrupts in kcov_remote_start_usb_softirq + - ata: libata-scsi: Set the RMB bit only for removable media devices + - powerpc/85xx: fix compile error without CONFIG_CRASH_DUMP + - kselftest/alsa: Ensure _GNU_SOURCE is defined + - thermal: core: Do not fail cdev registration because of invalid initial + state + - Bluetooth: hci_sync: Fix not using correct handle + - net/sched: initialize noop_qdisc owner + - tcp: use signed arithmetic in tcp_rtx_probe0_timed_out() + - drm/nouveau: don't attempt to schedule hpd_work on headless cards + - drm/xe/xe_gt_idle: use GT forcewake domain assertion + - drm/xe: flush engine buffers before signalling user fence on all engines + - drm/xe: Remove mem_access from guc_pc calls + - drm/xe: move disable_c6 call + - bnxt_en: Cap the size of HWRM_PORT_PHY_QCFG forwarded response + - iio: imu: bmi323: Fix trigger notification in case of error + - iio: pressure: bmp280: Fix BMP580 temperature reading + - iio: temperature: mlx90635: Fix ERR_PTR dereference in mlx90635_probe() + - thermal: ACPI: Invalidate trip points with temperature of 0 or below + - x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node() + - memblock: make memblock_set_node() also warn about use of MAX_NUMNODES + - perf script: Show also errors for --insn-trace option + - wifi: cfg80211: validate HE operation element parsing + - wifi: rtlwifi: Ignore IEEE80211_CONF_CHANGE_RETRY_LIMITS + - locking/atomic: scripts: fix ${atomic}_sub_and_test() kerneldoc + - ata: ahci: Do not apply Intel PCS quirk on Intel Alder Lake + - ata: libata-core: Add ATA_HORKAGE_NOLPM for Apacer AS340 + - ata: libata-core: Add ATA_HORKAGE_NOLPM for Crucial CT240BX500SSD1 + - ata: libata-core: Add ATA_HORKAGE_NOLPM for AMD Radeon S3 SSD + - kexec: fix the unexpected kexec_dprintk() macro + - ocfs2: update inode fsync transaction id in ocfs2_unlink and ocfs2_link + - dm-integrity: set discard_granularity to logical block size + - drm/bridge: aux-hpd-bridge: correct devm_drm_dp_hpd_bridge_add() stub + - iio: temperature: mcp9600: Fix temperature reading for negative values + - drm/mst: Fix NULL pointer dereference at drm_dp_add_payload_part2 + - riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled + - drm/xe: Properly handle alloc_guc_id() failure + - wifi: iwlwifi: mvm: support iwl_dev_tx_power_cmd_v8 + - wifi: iwlwifi: mvm: fix a crash on 7265 + - mei: vsc: Fix wrong invocation of ACPI SID method + - Upstream stable to v6.6.35, v6.9.6 + + * [SRU] Add support for intel trace hub for last platforms (LP: #2073926) // + Noble update: upstream stable patchset 2024-07-25 (LP: #2074091) + - intel_th: pci: Add Granite Rapids support + - intel_th: pci: Add Granite Rapids SOC support + - intel_th: pci: Add Sapphire Rapids SOC support + - intel_th: pci: Add Lunar Lake support + + * Fix L2CAP/LE/CPU/BV-02-C bluetooth certification failure (LP: #2072858) // + Noble update: upstream stable patchset 2024-07-25 (LP: #2074091) + - Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ + + * Noble update: upstream stable patchset 2024-07-22 (LP: #2073788) + - drm/i915/hwmon: Get rid of devm + - afs: Don't cross .backup mountpoint from backup volume + - erofs: avoid allocating DEFLATE streams before mounting + - vxlan: Fix regression when dropping packets due to invalid src addresses + - drm/sun4i: hdmi: Convert encoder to atomic + - drm/sun4i: hdmi: Move mode_set into enable + - f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode() + - media: lgdt3306a: Add a check against null-pointer-def + - drm/amdgpu: add error handle to avoid out-of-bounds + - wifi: rtw89: correct aSIFSTime for 6GHz band + - ata: pata_legacy: make legacy_exit() work again + - fsverity: use register_sysctl_init() to avoid kmemleak warning + - proc: Move fdinfo PTRACE_MODE_READ check into the inode .permission + operation + - platform/chrome: cros_ec: Handle events during suspend after resume + completion + - thermal/drivers/qcom/lmh: Check for SCM availability at probe + - soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request + - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx + - arm64: tegra: Correct Tegra132 I2C alias + - arm64: dts: qcom: qcs404: fix bluetooth device address + - md/raid5: fix deadlock that raid5d() wait for itself to clear + MD_SB_CHANGE_PENDING + - wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU + - wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power + - wifi: rtlwifi: rtl8192de: Fix low speed with WPA3-SAE + - wifi: rtlwifi: rtl8192de: Fix endianness issue in RX path + - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP + - arm64: dts: hi3798cv200: fix the size of GICR + - arm64: dts: ti: verdin-am62: Set memory size to 2gb + - media: mc: Fix graph walk in media_pipeline_start + - media: mc: mark the media devnode as registered from the, start + - media: mxl5xx: Move xpt structures off stack + - media: v4l2-core: hold videodev_lock until dev reg, finishes + - media: v4l: async: Properly re-initialise notifier entry in unregister + - media: v4l: async: Don't set notifier's V4L2 device if registering fails + - media: v4l: async: Fix notifier list entry init + - mmc: core: Add mmc_gpiod_set_cd_config() function + - mmc: sdhci: Add support for "Tuning Error" interrupts + - mmc: sdhci-acpi: Sort DMI quirks alphabetically + - mmc: sdhci-acpi: Fix Lenovo Yoga Tablet 2 Pro 1380 sdcard slot not working + - mmc: sdhci-acpi: Disable write protect detection on Toshiba WT10-A + - mmc: sdhci-acpi: Add quirk to enable pull-up on the card-detect GPIO on Asus + T100TA + - drm/fbdev-generic: Do not set physical framebuffer address + - fbdev: savage: Handle err return when savagefb_check_var failed + - drm/amdgpu/atomfirmware: add intergrated info v2.3 table + - 9p: add missing locking around taking dentry fid list + - drm/amd: Fix shutdown (again) on some SMU v13.0.4/11 platforms + - Revert "drm/amdkfd: fix gfx_target_version for certain 11.0.3 devices" + - KVM: SVM: WARN on vNMI + NMI window iff NMIs are outright masked + - KVM: arm64: Fix AArch32 register narrowing on userspace write + - KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode + - KVM: arm64: AArch32: Fix spurious trapping of conditional instructions + - LoongArch: Add all CPUs enabled by fdt to NUMA node 0 + - LoongArch: Override higher address bits in JUMP_VIRT_ADDR + - clk: bcm: dvp: Assign ->num before accessing ->hws + - clk: bcm: rpi: Assign ->num before accessing ->hws + - clk: qcom: clk-alpha-pll: fix rate setting for Stromer PLLs + - crypto: ecdsa - Fix module auto-load on add-key + - crypto: ecrdsa - Fix module auto-load on add_key + - crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak + - kbuild: Remove support for Clang's ThinLTO caching + - mm: fix race between __split_huge_pmd_locked() and GUP-fast + - filemap: add helper mapping_max_folio_size() + - iomap: fault in smaller chunks for non-large folio mappings + - i2c: acpi: Unbind mux adapters before delete + - HID: i2c-hid: elan: fix reset suspend current leakage + - scsi: core: Handle devices which return an unusually large VPD page count + - net/ipv6: Fix route deleting failure when metric equals 0 + - net/9p: fix uninit-value in p9_client_rpc() + - mm/ksm: fix ksm_pages_scanned accounting + - mm/ksm: fix ksm_zero_pages accounting + - kmsan: do not wipe out origin when doing partial unpoisoning + - tpm_tis: Do *not* flush uninitialized work + - intel_th: pci: Add Meteor Lake-S CPU support + - rtla/timerlat: Fix histogram report when a cpu count is 0 + - sparc64: Fix number of online CPUs + - mm/cma: drop incorrect alignment check in cma_init_reserved_mem + - mm/hugetlb: pass correct order_per_bit to cma_declare_contiguous_nid + - mm: /proc/pid/smaps_rollup: avoid skipping vma after getting mmap_lock again + - mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL + - selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages + - selftests/mm: fix build warnings on ppc64 + - watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin + - bonding: fix oops during rmmod + - wifi: ath10k: fix QCOM_RPROC_COMMON dependency + - kdb: Fix buffer overflow during tab-complete + - kdb: Use format-strings rather than '\0' injection in kdb_read() + - kdb: Fix console handling when editing and tab-completing commands + - kdb: Merge identical case statements in kdb_read() + - kdb: Use format-specifiers rather than memset() for padding in kdb_read() + - sparc: move struct termio to asm/termios.h + - drm/amdkfd: handle duplicate BOs in reserve_bo_and_cond_vms + - ext4: Fixes len calculation in mpage_journal_page_buffers + - ext4: set type of ac_groups_linear_remaining to __u32 to avoid overflow + - ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find() + - riscv: dts: starfive: Remove PMIC interrupt info for Visionfive 2 board + - ARM: dts: samsung: smdkv310: fix keypad no-autorepeat + - ARM: dts: samsung: smdk4412: fix keypad no-autorepeat + - ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat + - parisc: Define HAVE_ARCH_HUGETLB_UNMAPPED_AREA + - parisc: Define sigset_t in parisc uapi header + - s390/ap: Fix crash in AP internal function modify_bitmap() + - s390/cpacf: Split and rework cpacf query functions + - s390/cpacf: Make use of invalid opcode produce a link error + - i3c: master: svc: fix invalidate IBI type and miss call client IBI handler + - genirq/irqdesc: Prevent use-after-free in irq_find_at_or_after() + - ASoC: SOF: ipc4-topology: Fix input format query of process modules without + base extension + - ALSA: ump: Don't clear bank selection after sending a program change + - ALSA: ump: Don't accept an invalid UMP protocol number + - EDAC/amd64: Convert PCIBIOS_* return codes to errnos + - EDAC/igen6: Convert PCIBIOS_* return codes to errnos + - nfs: fix undefined behavior in nfs_block_bits() + - NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS + - eventfs: Fix a possible null pointer dereference in eventfs_find_events() + - eventfs: Keep the directories from having the same inode number as files + - tracefs: Clear EVENT_INODE flag in tracefs_drop_inode() + - btrfs: fix crash on racing fsync and size-extending write into prealloc + - btrfs: fix leak of qgroup extent records after transaction abort + - ALSA: seq: Fix incorrect UMP type for system messages + - powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH + - smb: client: fix deadlock in smb2_find_smb_tcon() + - smp: Provide 'setup_max_cpus' definition on UP too + - drm/xe/bb: assert width in xe_bb_create_job() + - crypto: starfive - Do not free stack buffer + - btrfs: qgroup: fix initialization of auto inherit array + - wifi: rtl8xxxu: enable MFP support with security flag of RX descriptor + - media: mgb4: Fix double debugfs remove + - media: ov2740: Fix LINK_FREQ and PIXEL_RATE control value reporting + - firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails + - LoongArch: Fix built-in DTB detection + - LoongArch: Fix entry point in kernel image header + - clk: qcom: apss-ipq-pll: use stromer ops for IPQ5018 to fix boot failure + - net/tcp: Don't consider TCP_CLOSE in TCP_AO_ESTABLISHED + - selftests: net: lib: support errexit with busywait + - selftests: net: lib: avoid error removing empty netns name + - cpufreq: amd-pstate: Fix the inconsistency in max frequency units + - mm/memory-failure: fix handling of dissolved but not taken off from buddy + pages + - selftests/mm: compaction_test: fix bogus test success on Aarch64 + - irqchip/riscv-intc: Prevent memory leak when riscv_intc_init_common() fails + - Revert "perf record: Reduce memory for recording PERF_RECORD_LOST_SAMPLES + event" + - hwmon: (ltc2992) Fix memory leak in ltc2992_parse_dt() + - riscv: enable HAVE_ARCH_HUGE_VMAP for XIP kernel + - btrfs: qgroup: update rescan message levels and error codes + - btrfs: qgroup: fix qgroup id collision across mounts + - btrfs: cache folio size and shift in extent_buffer + - btrfs: protect folio::private when attaching extent buffer folios + - bpf: fix multi-uprobe PID filtering logic + - powerpc/64/bpf: fix tail calls for PCREL addressing + - nilfs2: fix potential kernel bug due to lack of writeback flag waiting + - nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors + - Upstream stable to v6.6.34, v6.9.5 + + * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603) + - perf record: Delete session after stopping sideband thread + - perf probe: Add missing libgen.h header needed for using basename() + - iio: core: Leave private pointer NULL when no private data supplied + - greybus: lights: check return of get_channel_from_mode + - phy: qcom: qmp-combo: fix duplicate return in qmp_v4_configure_dp_phy + - f2fs: multidev: fix to recognize valid zero block address + - f2fs: fix to wait on page writeback in __clone_blkaddrs() + - fpga: manager: add owner module and take its refcount + - fpga: bridge: add owner module and take its refcount + - counter: linux/counter.h: fix Excess kernel-doc description warning + - perf annotate: Get rid of duplicate --group option item + - usb: typec: ucsi: always register a link to USB PD device + - usb: typec: ucsi: simplify partner's PD caps registration + - perf stat: Do not fail on metrics on s390 z/VM systems + - soundwire: cadence: fix invalid PDI offset + - dmaengine: idma64: Add check for dma_set_max_seg_size + - firmware: dmi-id: add a release callback function + - perf annotate: Fix annotation_calc_lines() to pass correct address to + get_srcline() + - serial: max3100: Lock port->lock when calling uart_handle_cts_change() + - serial: max3100: Update uart_driver_registered on driver removal + - serial: max3100: Fix bitwise types + - greybus: arche-ctrl: move device table to its right location + - PCI: tegra194: Fix probe path for Endpoint mode + - serial: sc16is7xx: add proper sched.h include for sched_set_fifo() + - module: don't ignore sysfs_create_link() failures + - interconnect: qcom: qcm2290: Fix mas_snoc_bimc QoS port assignment + - arm64: dts: meson: fix S4 power-controller node + - perf tests: Make "test data symbol" more robust on Neoverse N1 + - perf tests: Apply attributes to all events in object code reading test + - perf record: Fix debug message placement for test consumption + - dt-bindings: PCI: rcar-pci-host: Add missing IOMMU properties + - perf bench uprobe: Remove lib64 from libc.so.6 binary path + - f2fs: compress: fix to relocate check condition in + f2fs_{release,reserve}_compress_blocks() + - f2fs: compress: fix to relocate check condition in + f2fs_ioc_{,de}compress_file() + - f2fs: fix to relocate check condition in f2fs_fallocate() + - f2fs: fix to check pinfile flag in f2fs_move_file_range() + - iio: adc: stm32: Fixing err code to not indicate success + - riscv: dts: starfive: visionfive 2: Remove non-existing TDM hardware + - coresight: etm4x: Fix unbalanced pm_runtime_enable() + - perf docs: Document bpf event modifier + - perf test shell arm_coresight: Increase buffer size for Coresight basic + tests + - iio: pressure: dps310: support negative temperature values + - iio: buffer-dmaengine: export buffer alloc and free functions + - iio: add the IIO backend framework + - [CONFIG] Update CONFIG_IIO_BACKEND + - iio: adc: ad9467: convert to backend framework + - [Config] Update CONFIG_AD9467 + - iio: adc: adi-axi-adc: move to backend framework + - [Config] Update CONFIG_ADI_AXI_ADC + - iio: adc: adi-axi-adc: only error out in major version mismatch + - coresight: etm4x: Do not hardcode IOMEM access for register restore + - coresight: etm4x: Do not save/restore Data trace control registers + - coresight: etm4x: Safe access for TRCQCLTR + - coresight: etm4x: Fix access to resource selector registers + - vfio/pci: fix potential memory leak in vfio_intx_enable() + - fpga: region: add owner module and take its refcount + - udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb() + - udf: Convert udf_expand_file_adinicb() to use a folio + - microblaze: Remove gcc flag for non existing early_printk.c file + - microblaze: Remove early printk call from cpuinfo-static.c + - PCI: Wait for Link Training==0 before starting Link retrain + - perf intel-pt: Fix unassigned instruction op (discovered by MemorySanitizer) + - leds: pwm: Disable PWM when going to suspend + - ovl: remove upper umask handling from ovl_create_upper() + - PCI: of_property: Return error for int_map allocation failure + - VMCI: Fix an error handling path in vmci_guest_probe_device() + - dt-bindings: pinctrl: mediatek: mt7622: fix array properties + - pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs + - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger + - watchdog: bd9576: Drop "always-running" property + - watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in sa1100dog_probe() + - dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68] power-domains + - dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for sc8180x + - dmaengine: idxd: Avoid unnecessary destruction of file_ida + - usb: gadget: u_audio: Fix race condition use of controls after free during + gadget unbind. + - usb: gadget: u_audio: Clear uac pointer when freed. + - stm class: Fix a double free in stm_register_device() + - ppdev: Add an error check in register_device + - i2c: cadence: Avoid fifo clear after start + - i2c: synquacer: Fix an error handling path in synquacer_i2c_probe() + - perf bench internals inject-build-id: Fix trap divide when collecting just + one DSO + - perf ui browser: Don't save pointer to stack memory + - extcon: max8997: select IRQ_DOMAIN instead of depending on it + - dt-bindings: spmi: hisilicon,hisi-spmi-controller: fix binding references + - PCI/EDR: Align EDR_PORT_DPC_ENABLE_DSM with PCI Firmware r3.3 + - PCI/EDR: Align EDR_PORT_LOCATE_DSM with PCI Firmware r3.3 + - f2fs: support printk_ratelimited() in f2fs_printk() + - f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC + - f2fs: separate f2fs_gc_range() to use GC for a range + - f2fs: kill heap-based allocation + - f2fs: support file pinning for zoned devices + - f2fs: fix block migration when section is not aligned to pow2 + - perf ui browser: Avoid SEGV on title + - perf report: Avoid SEGV in report__setup_sample_type() + - perf thread: Fixes to thread__new() related to initializing comm + - perf symbols: Fix ownership of string in dso__load_vmlinux() + - f2fs: compress: fix to update i_compr_blocks correctly + - f2fs: deprecate io_bits + - f2fs: introduce get_available_block_count() for cleanup + - f2fs: compress: fix error path of inc_valid_block_count() + - f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem + lock + - f2fs: fix to release node block count in error path of f2fs_new_node_page() + - f2fs: compress: don't allow unaligned truncation on released compress inode + - serial: sh-sci: protect invalidating RXDMA on shutdown + - libsubcmd: Fix parse-options memory leak + - perf daemon: Fix file leak in daemon_session__control + - f2fs: fix to add missing iput() in gc_data_segment() + - usb: fotg210: Add missing kernel doc description + - perf stat: Don't display metric header for non-leader uncore events + - perf tools: Use pmus to describe type from attribute + - perf tools: Add/use PMU reverse lookup from config to name + - perf pmu: Assume sysfs events are always the same case + - perf pmu: Count sys and cpuid JSON events separately + - LoongArch: Fix callchain parse error with kernel tracepoint events again + - s390/vdso64: filter out munaligned-symbols flag for vdso + - s390/vdso: Generate unwind information for C modules + - s390/vdso: Create .build-id links for unstripped vdso files + - s390/vdso: Use standard stack frame layout + - s390/ipl: Fix incorrect initialization of len fields in nvme reipl block + - s390/ipl: Fix incorrect initialization of nvme dump block + - s390/boot: Remove alt_stfle_fac_list from decompressor + - dt-bindings: PCI: rockchip,rk3399-pcie: Add missing maxItems to ep-gpios + - gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node + match + - eventfs: Do not differentiate the toplevel events directory + - eventfs: Create eventfs_root_inode to store dentry + - eventfs/tracing: Add callback for release of an eventfs_inode + - eventfs: Free all of the eventfs_inode after RCU + - eventfs: Have "events" directory get permissions from its parent + - dt-bindings: adc: axi-adc: update bindings for backend framework + - dt-bindings: adc: axi-adc: add clocks property + - Input: ims-pcu - fix printf string overflow + - mmc: sdhci_am654: Add tuning algorithm for delay chain + - mmc: sdhci_am654: Write ITAPDLY for DDR52 timing + - mmc: sdhci_am654: Add OTAP/ITAP delay enable + - mmc: sdhci_am654: Add ITAPDLYSEL in sdhci_j721e_4bit_set_clock + - mmc: sdhci_am654: Fix ITAPDLY for HS400 timing + - Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation + - media: v4l: Don't turn on privacy LED if streamon fails + - media: ov2680: Clear the 'ret' variable on success + - media: ov2680: Allow probing if link-frequencies is absent + - media: ov2680: Do not fail if data-lanes property is absent + - drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk + - drm/msm/dpu: Always flush the slave INTF on the CTL + - drm/mediatek: dp: Fix mtk_dp_aux_transfer return value + - drm/meson: gate px_clk when setting rate + - um: Fix return value in ubd_init() + - um: vector: fix bpfflash parameter evaluation + - fs/ntfs3: Check 'folio' pointer for NULL + - fs/ntfs3: Use 64 bit variable to avoid 32 bit overflow + - fs/ntfs3: Use variable length array instead of fixed size + - drm/msm/dpu: Add callback function pointer check before its call + - drm/bridge: tc358775: fix support for jeida-18 and jeida-24 + - media: stk1160: fix bounds checking in stk1160_copy_video() + - Input: cyapa - add missing input core locking to suspend/resume functions + - drm/amdgpu: init microcode chip name from ip versions + - drm/amdgpu: Fix buffer size in gfx_v9_4_3_init_ cp_compute_microcode() and + rlc_microcode() + - media: mediatek: vcodec: fix possible unbalanced PM counter + - tools/arch/x86/intel_sdsi: Fix maximum meter bundle length + - tools/arch/x86/intel_sdsi: Fix meter_show display + - tools/arch/x86/intel_sdsi: Fix meter_certificate decoding + - platform/x86: thinkpad_acpi: Take hotkey_mutex during hotkey_exit() + - media: flexcop-usb: fix sanity check of bNumEndpoints + - powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp + - um: Fix the -Wmissing-prototypes warning for __switch_mm + - um: Fix the -Wmissing-prototypes warning for get_thread_reg + - um: Fix the declaration of kasan_map_memory + - cxl/trace: Correct DPA field masks for general_media & dram events + - cxl/region: Fix cxlr_pmem leaks + - media: sunxi: a83-mips-csi2: also select GENERIC_PHY + - media: cec: cec-adap: always cancel work in cec_transmit_msg_fh + - media: cec: cec-api: add locking in cec_release() + - media: cec: core: avoid recursive cec_claim_log_addrs + - media: cec: core: avoid confusing "transmit timed out" message + - Revert "drm/bridge: ti-sn65dsi83: Fix enable error path" + - drm: zynqmp_dpsub: Always register bridge + - selftests/powerpc/dexcr: Add -no-pie to hashchk tests + - drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails + - ASoC: tas2781: Fix a warning reported by robot kernel test + - null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION() + - ALSA: hda/cs_dsp_ctl: Use private_free for control cleanup + - ALSA: hda: cs35l56: Fix lifetime of cs_dsp instance + - ASoC: mediatek: mt8192: fix register configuration for tdm + - drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations + - blk-cgroup: fix list corruption from resetting io stat + - blk-cgroup: fix list corruption from reorder of WRITE ->lqueued + - blk-cgroup: Properly propagate the iostat update up the hierarchy + - regulator: bd71828: Don't overwrite runtime voltages + - xen/x86: add extra pages to unpopulated-alloc if available + - perf/arm-dmc620: Fix lockdep assert in ->event_init() + - x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when + UNWINDER_FRAME_POINTER=y + - [Config] Update CONFIG_ARCH_WANT_FRAME_POINTERS + - net: Always descend into dsa/ folder with CONFIG_NET_DSA enabled + - ipv6: sr: fix missing sk_buff release in seg6_input_core + - selftests: net: kill smcrouted in the cleanup logic in amt.sh + - nfc: nci: Fix uninit-value in nci_rx_work + - ASoC: tas2552: Add TX path for capturing AUDIO-OUT data + - ASoC: tas2781: Fix wrong loading calibrated data sequence + - NFSv4: Fixup smatch warning for ambiguous return + - nfs: keep server info for remounts + - sunrpc: fix NFSACL RPC retry on soft mount + - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL + - regulator: pickable ranges: don't always cache vsel + - regulator: tps6287x: Force writing VSEL bit + - af_unix: Update unix_sk(sk)->oob_skb under sk_receive_queue lock. + - ipv6: sr: fix memleak in seg6_hmac_init_algo + - regulator: tps6594-regulator: Correct multi-phase configuration + - tcp: Fix shift-out-of-bounds in dctcp_update_alpha(). + - pNFS/filelayout: fixup pNfs allocation modes + - openvswitch: Set the skbuff pkt_type for proper pmtud support. + - arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY + - rv: Update rv_en(dis)able_monitor doc to match kernel-doc + - net: lan966x: Remove ptp traps in case the ptp is not enabled. + - virtio: delete vq in vp_find_vqs_msix() when request_irq() fails + - i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame + - Revert "ixgbe: Manual AN-37 for troublesome link partners for X550 SFI" + - net: fec: avoid lock evasion when reading pps_enable + - tls: fix missing memory barrier in tls_init + - net: relax socket state check at accept time. + - nfc: nci: Fix handling of zero-length payload packets in nci_rx_work() + - drivers/xen: Improve the late XenStore init protocol + - ice: Interpret .set_channels() input differently + - kasan, fortify: properly rename memintrinsics + - tracing/probes: fix error check in parse_btf_field() + - tpm_tis_spi: Account for SPI header when allocating TPM SPI xfer buffer + - netfilter: nfnetlink_queue: acquire rcu_read_lock() in + instance_destroy_rcu() + - netfilter: ipset: Add list flush to cancel_gc + - netfilter: nft_payload: restore vlan q-in-q match support + - spi: Don't mark message DMA mapped when no transfer in it is + - dma-mapping: benchmark: fix up kthread-related error handling + - dma-mapping: benchmark: fix node id validation + - dma-mapping: benchmark: handle NUMA_NO_NODE correctly + - nvme-multipath: fix io accounting on failover + - nvmet: fix ns enable/disable possible hang + - drm/amd/display: Enable colorspace property for MST connectors + - net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8061 + - net/mlx5: Lag, do bond only if slaves agree on roce state + - net/mlx5: Fix MTMP register capability offset in MCAM register + - net/mlx5: Use mlx5_ipsec_rx_status_destroy to correctly delete status rules + - net/mlx5e: Fix IPsec tunnel mode offload feature check + - net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer + exhaustion + - net/mlx5e: Fix UDP GSO for encapsulated packets + - dma-buf/sw-sync: don't enable IRQ from sync_print_obj() + - bpf: Fix potential integer overflow in resolve_btfids + - ALSA: jack: Use guard() for locking + - ALSA: core: Remove debugfs at disconnection + - ALSA: hda/realtek: Adjust G814JZR to use SPI init for amp + - enic: Validate length of nl attributes in enic_set_vf_port + - af_unix: Annotate data-race around unix_sk(sk)->addr. + - af_unix: Read sk->sk_hash under bindlock during bind(). + - Octeontx2-pf: Free send queue buffers incase of leaf to inner + - net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM + - ASoC: cs42l43: Only restrict 44.1kHz for the ASP + - bpf: Allow delete from sockmap/sockhash only if update is allowed + - net:fec: Add fec_enet_deinit() + - net: micrel: Fix lan8841_config_intr after getting out of sleep mode + - ice: fix accounting if a VLAN already exists + - selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky + - selftests: mptcp: add ms units for tc-netem delay + - selftests: mptcp: join: mark 'fail' tests as flaky + - ALSA: seq: Fix missing bank setup between MIDI1/MIDI2 UMP conversion + - ALSA: seq: Don't clear bank selection at event -> UMP MIDI2 conversion + - net: ti: icssg-prueth: Fix start counter for ft1 filter + - netfilter: nft_payload: skbuff vlan metadata mangle support + - netfilter: tproxy: bail out if IP has been disabled on the device + - netfilter: nft_fib: allow from forward/input without iif selector + - net/sched: taprio: make q->picos_per_byte available to fill_sched_entry() + - net/sched: taprio: extend minimum interval restriction to entire cycle too + - kconfig: fix comparison to constant symbols, 'm', 'n' + - drm/i915/guc: avoid FIELD_PREP warning + - kheaders: use `command -v` to test for existence of `cpio` + - spi: stm32: Don't warn about spurious interrupts + - net: dsa: microchip: fix RGMII error in KSZ DSA driver + - net: ena: Reduce lines with longer column width boundary + - net: ena: Fix redundant device NUMA node override + - ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound + - ALSA: seq: Fix yet another spot for system message conversion + - powerpc/pseries/lparcfg: drop error message from guest name lookup + - drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel + - drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel + - drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 panel + - hwmon: (intel-m10-bmc-hwmon) Fix multiplier for N6000 board power sensor + - hwmon: (shtc1) Fix property misspelling + - ALSA: seq: ump: Fix swapped song position pointer data + - ALSA: timer: Set lower bound of start tick time + - x86/efistub: Omit physical KASLR when memory reservations exist + - efi: libstub: only free priv.runtime_map when allocated + - x86/pci: Skip early E820 check for ECAM region + - KVM: x86: Don't advertise guest.MAXPHYADDR as host.MAXPHYADDR in CPUID + - genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline + - platform/x86/intel/tpmi: Handle error from tpmi_process_info() + - platform/x86/intel-uncore-freq: Don't present root domain on error + - perf sched timehist: Fix -g/--call-graph option failure + - f2fs: write missing last sum blk of file pinning section + - f2fs: use f2fs_{err,info}_ratelimited() for cleanup + - SUNRPC: Fix loop termination condition in gss_free_in_token_pages() + - riscv: prevent pt_regs corruption for secondary idle threads + - riscv: stacktrace: fixed walk_stackframe() + - perf build: Fix out of tree build related to installation of sysreg-defs + - dt-bindings: pinctrl: qcom: update functions to match with driver + - usb: typec: ucsi: allow non-partner GET_PDOS for Qualcomm devices + - perf report: Fix PAI counter names for s390 virtual machines + - PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host + - perf map: Remove kernel map before updating start and end addresses + - riscv: dts: starfive: visionfive 2: Remove non-existing I2S hardware + - pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces + - riscv: Flush the instruction cache during SMP bringup + - usb: xhci: check if 'requested segments' exceeds ERST capacity + - spmi: pmic-arb: Replace three IS_ERR() calls by null pointer checks in + spmi_pmic_arb_probe() + - perf symbols: Remove map from list before updating addresses + - perf symbols: Update kcore map before merging in remaining symbols + - s390/ftrace: Use unwinder instead of __builtin_return_address() + - s390/stacktrace: Merge perf_callchain_user() and arch_stack_walk_user() + - s390/stacktrace: Skip first user stack frame + - s390/stacktrace: Improve detection of invalid instruction pointers + - s390/vdso: Introduce and use struct stack_frame_vdso_wrapper + - s390/stackstrace: Detect vdso stack frames + - s390/ap: Fix bind complete udev event sent after each AP bus scan + - ocfs2: correctly use ocfs2_find_next_zero_bit() + - mailbox: mtk-cmdq: Fix pm_runtime_get_sync() warning in mbox shutdown + - Input: ioc3kbd - add device table + - phy: qcom: qmp-combo: fix sm8650 voltage swing table + - media: ti: j721e-csi2rx: Fix races while restarting DMA + - drm/msm/dpu: Allow configuring multiple active DSC blocks + - drm: Make drivers depends on DRM_DW_HDMI + - [Config] Drivers now depend on DRM_DW_HDMI + - string: Prepare to merge strscpy_kunit.c into string_kunit.c + - string: Prepare to merge strcat KUnit tests into string_kunit.c + - drm/msm/adreno: fix CP cycles stat retrieval on a7xx + - printk: Fix LOG_CPU_MAX_BUF_SHIFT when BASE_SMALL is enabled + - powerpc/bpf/32: Fix failing test_bpf tests + - KVM: PPC: Book3S HV nestedv2: Cancel pending DEC exception + - KVM: PPC: Book3S HV nestedv2: Fix an error handling path in + gs_msg_ops_kvmhv_nestedv2_config_fill_info() + - KVM: arm64: Destroy mpidr_data for 'late' vCPU creation + - Bluetooth: ISO: Handle PA sync when no BIGInfo reports are generated + - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() + - ubsan: Restore dependency on ARCH_HAS_UBSAN + - selftests: forwarding: Have RET track kselftest framework constants + - selftests: forwarding: Convert log_test() to recognize RET values + - selftests: net: Unify code of busywait() and slowwait() + - selftests/net: use tc rule to filter the na packet + - virtio_balloon: Give the balloon its own wakeup source + - riscv: cpufeature: Fix thead vector hwcap removal + - riscv: cpufeature: Fix extension subset checking + - riscv: selftests: Add hwprobe binaries to .gitignore + - idpf: Interpret .set_channels() input differently + - null_blk: fix null-ptr-dereference while configuring 'power' and + 'submit_queues' + - netfs: Fix setting of BDP_ASYNC from iocb flags + - cifs: Set zero_point in the copy_file_range() and remap_file_range() + - cifs: Fix missing set of remote_i_size + - selftests: net: lib: set 'i' as local + - nvme: fix multipath batched completion accounting + - netkit: Fix setting mac address in l2 mode + - netkit: Fix pkt_type override upon netkit pass verdict + - null_blk: Fix return value of nullb_device_power_store() + - idpf: don't enable NAPI and interrupts prior to allocating Rx buffers + - selftests: mptcp: join: mark 'fastclose' tests as flaky + - drm/xe: Add dbg messages on the suspend resume functions. + - drm/xe: check pcode init status only on root gt of root tile + - drm/xe: Change pcode timeout to 50msec while polling again + - drm/xe: Only use reserved BCS instances for usm migrate exec queue + - sd: also set max_user_sectors when setting max_sectors + - block: stack max_user_sectors + - ipv6: introduce dst_rt6_info() helper + - inet: introduce dst_rtable() helper + - net: fix __dst_negative_advice() race + - ice: fix 200G PHY types to link speed mapping + - x86/topology/intel: Unlock CPUID before evaluating anything + - Upstream stable to v6.6.33, v6.9.4 + + * Reenable CONFIG_UBSAN for noble (LP: #2076650) + - ubsan: Remove CONFIG_UBSAN_SANITIZE_ALL + - [Config] Remove CONFIG_UBSAN_SANITIZE_ALL + + * Dangling symlink to linux-lib-rust when Rust is disabled (LP: #2072592) + - [Packaging] Check do_lib_rust before linking Rust lib files + + * kdump doesn't work with UEFI secure boot and kernel lockdown enabled on + ARM64 (LP: #2033007) + - [Config]: Enable CONFIG_KEXEC_IMAGE_VERIFY_SIG on arm64 + + * net/sched: Fix conntrack use-after-free (LP: #2073092) + - net/sched: Fix UAF when resolving a clash + + * No sound on Huawei Matebook D14 AMD since Linux 6.8.0-38 [regression] + (LP: #2073049) + - ASoC: amd: acp: fix for acp platform device creation failure + + * i915: Fixup regressions introduced with enabling single CCS engine + (LP: #2072755) + - drm/i915/gt: Fix CCS id's calculation for CCS mode setting + + * [Ubuntu 24.04] FW1060.00 (NH1060_026) sosreport is running to Kernel OOPS + crash (LP: #2070358) + - nfsd: initialise nfsd_info.mutex early. + + * 6.8 generic & amdpgu / polaris (LP: #2072428) + - drm/amdgpu: Adjust logic in amdgpu_device_partner_bandwidth() + + * md: nvme over tcp with a striped underlying md raid device leads to data + corruption (LP: #2075110) + - md/md-bitmap: fix writing non bitmap pages + + * Linux 6.8 fails to boot on ARM64 if any param is more than 146 chars + (LP: #2069534) + - SAUCE: arm64: v6.8: cmdline param >= 146 chars kills kernel + + * CVE-2024-39484 + - mmc: davinci: Don't strip remove function when driver is builtin + + * CVE-2024-39292 + - um: Add winch to winch_handlers before registering winch IRQ + + * Miscellaneous upstream changes + - bnx2x: Fix multiple UBSAN array-index-out-of-bounds + + -- Roxana Nicolescu Tue, 13 Aug 2024 12:20:36 +0200 + +linux (6.8.0-40.40) noble; urgency=medium + + * noble/linux: 6.8.0-40.40 -proposed tracker (LP: #2072201) + + * FPS of glxgear with fullscreen is too low on MTL platform (LP: #2069380) + - drm/i915: Bypass LMEMBAR/GTTMMADR for MTL stolen memory access + + * a critical typo in the code managing the ASPM settings for PCI Express + devices (LP: #2071889) + - PCI/ASPM: Restore parent state to parent, child state to child + + * [UBUNTU 24.04] IOMMU DMA mode changed in kernel config causes massive + throughput degradation for PCI-related network workloads (LP: #2071471) + - [Config] Set IOMMU_DEFAULT_DMA_STRICT=n and IOMMU_DEFAULT_DMA_LAZY=yes for + s390x + + * UBSAN: array-index-out-of-bounds in + /build/linux-D15vQj/linux-6.5.0/drivers/md/bcache/bset.c:1098:3 + (LP: #2039368) + - bcache: fix variable length array abuse in btree_iter + + * Mute/mic LEDs and speaker no function on EliteBook 645/665 G11 + (LP: #2071296) + - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook 645/665 + G11. + + * failed to enable IPU6 camera sensor on kernel >= 6.8: ivsc_ace + intel_vsc-5db76cf6-0a68-4ed6-9b78-0361635e2447: switch camera to host + failed: -110 (LP: #2067364) + - mei: vsc: Don't stop/restart mei device during system suspend/resume + - SAUCE: media: ivsc: csi: don't count privacy on as error + - SAUCE: media: ivsc: csi: add separate lock for v4l2 control handler + - SAUCE: media: ivsc: csi: remove privacy status in struct mei_csi + - SAUCE: mei: vsc: Enhance IVSC chipset stability during warm reboot + - SAUCE: mei: vsc: Enhance SPI transfer of IVSC rom + - SAUCE: mei: vsc: Utilize the appropriate byte order swap function + - SAUCE: mei: vsc: Prevent timeout error with added delay post-firmware + download + + * failed to probe camera sensor on Dell XPS 9315: ov01a10 i2c-OVTI01A0:00: + failed to check hwcfg: -22 (LP: #2070251) + - ACPI: utils: Make acpi_handle_path() not static + - ACPI: property: Ignore bad graph port nodes on Dell XPS 9315 + - ACPI: property: Polish ignoring bad data nodes + - ACPI: scan: Ignore camera graph port nodes on all Dell Tiger, Alder and + Raptor Lake models + + * Update amd_sfh for AMD strix series (LP: #2058331) + - HID: amd_sfh: Increase sensor command timeout + - HID: amd_sfh: Improve boot time when SFH is available + - HID: amd_sfh: Extend MP2 register access to SFH + - HID: amd_sfh: Set the AMD SFH driver to depend on x86 + + * RFIM and SAGV Linux Support for G10 models (LP: #2070158) + - drm/i915/display: Add meaningful traces for QGV point info error handling + - drm/i915/display: Extract code required to calculate max qgv/psf gv point + - drm/i915/display: extract code to prepare qgv points mask + - drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation + - drm/i915/display: handle systems with duplicate psf gv points + - drm/i915/display: force qgv check after the hw state readout + + * Update amd-pmf for AMD strix series (LP: #2058330) + - platform/x86/amd/pmf: Differentiate PMF ACPI versions + - platform/x86/amd/pmf: Disable debugfs support for querying power thermals + - platform/x86/amd/pmf: Add support to get sbios requests in PMF driver + - platform/x86/amd/pmf: Add support to notify sbios heart beat event + - platform/x86/amd/pmf: Add support to get APTS index numbers for static + slider + - platform/x86/amd/pmf: Add support to get sps default APTS index values + - platform/x86/amd/pmf: Update sps power thermals according to the platform- + profiles + + * noble:linux: ADT ubuntu-regression-suite misses fakeroot dependency + (LP: #2070042) + - [DEP-8] Add missing fakeroot dependency + + * Noble update: v6.8.12 upstream stable release (LP: #2071621) + - sunrpc: use the struct net as the svc proc private + - x86/tsc: Trust initial offset in architectural TSC-adjust MSRs + - selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly + - ftrace: Fix possible use-after-free issue in ftrace_location() + - Revert "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD" + - arm64/fpsimd: Avoid erroneous elide of user state reload + - Reapply "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD" + - tty: n_gsm: fix missing receive state reset after mode switch + - speakup: Fix sizeof() vs ARRAY_SIZE() bug + - serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler + - serial: 8250_bcm7271: use default_mux_rate if possible + - serial: 8520_mtk: Set RTS on shutdown for Rx in-band wakeup + - Input: try trimming too long modalias strings + - io_uring: fail NOP if non-zero op flags is passed in + - Revert "r8169: don't try to disable interrupts if NAPI is, scheduled + already" + - r8169: Fix possible ring buffer corruption on fragmented Tx packets. + - ring-buffer: Fix a race between readers and resize checks + - net: mana: Fix the extra HZ in mana_hwc_send_request + - tools/latency-collector: Fix -Wformat-security compile warns + - tools/nolibc/stdlib: fix memory error in realloc() + - net: ti: icssg_prueth: Fix NULL pointer dereference in prueth_probe() + - net: lan966x: remove debugfs directory in probe() error path + - net: smc91x: Fix m68k kernel compilation for ColdFire CPU + - nilfs2: fix use-after-free of timer for log writer thread + - nilfs2: fix unexpected freezing of nilfs_segctor_sync() + - nilfs2: fix potential hang in nilfs_detach_log_writer() + - fs/ntfs3: Remove max link count info display during driver init + - fs/ntfs3: Taking DOS names into account during link counting + - fs/ntfs3: Fix case when index is reused during tree transformation + - fs/ntfs3: Break dir enumeration if directory contents error + - ksmbd: avoid to send duplicate oplock break notifications + - ksmbd: ignore trailing slashes in share paths + - ALSA: core: Fix NULL module pointer assignment at card init + - ALSA: Fix deadlocks with kctl removals at disconnection + - KEYS: asymmetric: Add missing dependency on CRYPTO_SIG + - [Config] updateconfigs for CRYPTO_SIG + - KEYS: asymmetric: Add missing dependencies of FIPS_SIGNATURE_SELFTEST + - HID: nintendo: Fix N64 controller being identified as mouse + - dmaengine: xilinx: xdma: Clarify kdoc in XDMA driver + - wifi: mac80211: don't use rate mask for scanning + - wifi: mac80211: ensure beacon is non-S1G prior to extracting the beacon + timestamp field + - wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt + class + - dt-bindings: rockchip: grf: Add missing type to 'pcie-phy' node + - HID: mcp-2221: cancel delayed_work only when CONFIG_IIO is enabled + - net: usb: qmi_wwan: add Telit FN920C04 compositions + - drm/amd/display: Set color_mgmt_changed to true on unsuspend + - drm/amdgpu: Update BO eviction priorities + - drm/amd/pm: Restore config space after reset + - drm/amdkfd: Add VRAM accounting for SVM migration + - drm/amdgpu: Fix the ring buffer size for queue VM flush + - Revert "net: txgbe: fix i2c dev name cannot match clkdev" + - Revert "net: txgbe: fix clk_name exceed MAX_DEV_ID limits" + - cpu: Ignore "mitigations" kernel parameter if CPU_MITIGATIONS=n + - LoongArch: Lately init pmu after smp is online + - drm/etnaviv: fix tx clock gating on some GC7000 variants + - selftests: sud_test: return correct emulated syscall value on RISC-V + - riscv: thead: Rename T-Head PBMT to MAE + - [Config] updateconfigs for ERRATA_THEAD_MAE + - riscv: T-Head: Test availability bit before enabling MAE errata + - sched/isolation: Fix boot crash when maxcpus < first housekeeping CPU + - ASoC: Intel: bytcr_rt5640: Apply Asus T100TA quirk to Asus T100TAM too + - regulator: irq_helpers: duplicate IRQ name + - ALSA: hda: cs35l56: Exit cache-only after cs35l56_wait_for_firmware_boot() + - ASoC: SOF: ipc4-pcm: Use consistent name for snd_sof_pcm_stream pointer + - ASoC: SOF: ipc4-pcm: Use consistent name for sof_ipc4_timestamp_info pointer + - ASoC: SOF: ipc4-pcm: Introduce generic sof_ipc4_pcm_stream_priv + - ASoC: SOF: pcm: Restrict DSP D0i3 during S0ix to IPC3 + - ASoC: acp: Support microphone from device Acer 315-24p + - ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating + - ASoC: dt-bindings: rt5645: add cbj sleeve gpio property + - ASoC: rt722-sdca: modify channel number to support 4 channels + - ASoC: rt722-sdca: add headset microphone vrefo setting + - regulator: qcom-refgen: fix module autoloading + - regulator: vqmmc-ipq4019: fix module autoloading + - ASoC: cs35l41: Update DSP1RX5/6 Sources for DSP config + - ASoC: rt715: add vendor clear control register + - ASoC: rt715-sdca: volume step modification + - KVM: selftests: Add test for uaccesses to non-existent vgic-v2 CPUIF + - Input: xpad - add support for ASUS ROG RAIKIRI + - btrfs: take the cleaner_mutex earlier in qgroup disable + - EDAC/versal: Do not register for NOC errors + - fpga: dfl-pci: add PCI subdevice ID for Intel D5005 card + - bpf, x86: Fix PROBE_MEM runtime load check + - ALSA: emu10k1: make E-MU FPGA writes potentially more reliable + - softirq: Fix suspicious RCU usage in __do_softirq() + - platform/x86: ISST: Add Grand Ridge to HPM CPU list + - ASoC: da7219-aad: fix usage of device_get_named_child_node() + - ASoC: cs35l56: fix usages of device_get_named_child_node() + - ALSA: hda: intel-dsp-config: harden I2C/I2S codec detection + - Input: amimouse - mark driver struct with __refdata to prevent section + mismatch + - drm/amdgpu: Fix VRAM memory accounting + - drm/amd/display: Ensure that dmcub support flag is set for DCN20 + - drm/amd/display: Add dtbclk access to dcn315 + - drm/amd/display: Allocate zero bw after bw alloc enable + - drm/amd/display: Add VCO speed parameter for DCN31 FPU + - drm/amd/display: Fix DC mode screen flickering on DCN321 + - drm/amd/display: Disable seamless boot on 128b/132b encoding + - drm/amdkfd: Flush the process wq before creating a kfd_process + - x86/mm: Remove broken vsyscall emulation code from the page fault code + - nvme: find numa distance only if controller has valid numa id + - nvmet-auth: return the error code to the nvmet_auth_host_hash() callers + - nvmet-auth: replace pr_debug() with pr_err() to report an error. + - nvme: cancel pending I/O if nvme controller is in terminal state + - nvmet-tcp: fix possible memory leak when tearing down a controller + - nvmet: fix nvme status code when namespace is disabled + - nvme-tcp: strict pdu pacing to avoid send stalls on TLS + - epoll: be better about file lifetimes + - nvmet: prevent sprintf() overflow in nvmet_subsys_nsid_exists() + - openpromfs: finish conversion to the new mount API + - crypto: bcm - Fix pointer arithmetic + - firmware: qcom: qcm: fix unused qcom_scm_qseecom_allowlist + - mm/slub, kunit: Use inverted data to corrupt kmem cache + - firmware: raspberrypi: Use correct device for DMA mappings + - ecryptfs: Fix buffer size for tag 66 packet + - nilfs2: fix out-of-range warning + - parisc: add missing export of __cmpxchg_u8() + - crypto: ccp - drop platform ifdef checks + - crypto: x86/nh-avx2 - add missing vzeroupper + - crypto: x86/sha256-avx2 - add missing vzeroupper + - crypto: x86/sha512-avx2 - add missing vzeroupper + - s390/cio: fix tracepoint subchannel type field + - io_uring: use the right type for work_llist empty check + - rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow + - rcu: Fix buffer overflow in print_cpu_stall_info() + - ARM: configs: sunxi: Enable DRM_DW_HDMI + - jffs2: prevent xattr node from overflowing the eraseblock + - libfs: Re-arrange locking in offset_iterate_dir() + - libfs: Define a minimum directory offset + - libfs: Add simple_offset_empty() + - maple_tree: Add mtree_alloc_cyclic() + - libfs: Convert simple directory offsets to use a Maple Tree + - libfs: Fix simple_offset_rename_exchange() + - libfs: Add simple_offset_rename() API + - shmem: Fix shmem_rename2() + - io-wq: write next_work before dropping acct_lock + - mm/userfaultfd: Do not place zeropages when zeropages are disallowed + - s390/mm: Re-enable the shared zeropage for !PV and !skeys KVM guests + - crypto: octeontx2 - add missing check for dma_map_single + - crypto: qat - improve error message in adf_get_arbiter_mapping() + - crypto: qat - improve error logging to be consistent across features + - soc: qcom: pmic_glink: don't traverse clients list without a lock + - soc: qcom: pmic_glink: notify clients about the current state + - firmware: qcom: scm: Fix __scm and waitq completion variable initialization + - soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE + - null_blk: Fix missing mutex_destroy() at module removal + - crypto: qat - validate slices count returned by FW + - hwrng: stm32 - use logical OR in conditional + - hwrng: stm32 - put IP into RPM suspend on failure + - hwrng: stm32 - repair clock handling + - kunit/fortify: Fix mismatched kvalloc()/vfree() usage + - io_uring/net: remove dependency on REQ_F_PARTIAL_IO for sr->done_io + - io_uring/net: fix sendzc lazy wake polling + - soc: qcom: pmic_glink: Make client-lock non-sleeping + - lkdtm: Disable CFI checking for perms functions + - md: fix resync softlockup when bitmap size is less than array size + - crypto: qat - specify firmware files for 402xx + - block: refine the EOF check in blkdev_iomap_begin + - block: fix and simplify blkdevparts= cmdline parsing + - block: support to account io_ticks precisely + - wifi: ath10k: poll service ready message before failing + - wifi: brcmfmac: pcie: handle randbuf allocation failure + - wifi: ath11k: don't force enable power save on non-running vdevs + - bpftool: Fix missing pids during link show + - libbpf: Prevent null-pointer dereference when prog to load has no BTF + - wifi: ath12k: use correct flag field for 320 MHz channels + - wifi: mt76: mt7915: workaround too long expansion sparse warnings + - x86/boot: Ignore relocations in .notes sections in walk_relocs() too + - wifi: ieee80211: fix ieee80211_mle_basic_sta_prof_size_ok() + - wifi: iwlwifi: mvm: Do not warn on invalid link on scan complete + - wifi: iwlwifi: mvm: allocate STA links only for active links + - wifi: mac80211: don't select link ID if not provided in scan request + - wifi: iwlwifi: implement can_activate_links callback + - wifi: iwlwifi: mvm: fix active link counting during recovery + - wifi: iwlwifi: mvm: select STA mask only for active links + - wifi: iwlwifi: reconfigure TLC during HW restart + - wifi: iwlwifi: mvm: fix check in iwl_mvm_sta_fw_id_mask + - sched/fair: Add EAS checks before updating root_domain::overutilized + - ACPI: bus: Indicate support for _TFP thru _OSC + - ACPI: bus: Indicate support for more than 16 p-states thru _OSC + - ACPI: bus: Indicate support for the Generic Event Device thru _OSC + - ACPI: Fix Generic Initiator Affinity _OSC bit + - ACPI: bus: Indicate support for IRQ ResourceSource thru _OSC + - enetc: avoid truncating error message + - qed: avoid truncating work queue length + - mlx5: avoid truncating error message + - mlx5: stop warning for 64KB pages + - bitops: add missing prototype check + - dlm: fix user space lock decision to copy lvb + - wifi: carl9170: re-fix fortified-memset warning + - bpftool: Mount bpffs on provided dir instead of parent dir + - bpf: Pack struct bpf_fib_lookup + - bpf: prevent r10 register from being marked as precise + - x86/microcode/AMD: Avoid -Wformat warning with clang-15 + - scsi: ufs: qcom: Perform read back after writing reset bit + - scsi: ufs: qcom: Perform read back after writing REG_UFS_SYS1CLK_1US + - scsi: ufs: qcom: Perform read back after writing unipro mode + - scsi: ufs: qcom: Perform read back after writing CGC enable + - scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV + - scsi: ufs: core: Perform read back after writing UTP_TASK_REQ_LIST_BASE_H + - scsi: ufs: core: Perform read back after disabling interrupts + - scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL + - ACPI: LPSS: Advertise number of chip selects via property + - EDAC/skx_common: Allow decoding of SGX addresses + - locking/atomic/x86: Correct the definition of __arch_try_cmpxchg128() + - irqchip/alpine-msi: Fix off-by-one in allocation error path + - irqchip/loongson-pch-msi: Fix off-by-one on allocation error path + - ACPI: disable -Wstringop-truncation + - gfs2: Don't forget to complete delayed withdraw + - gfs2: Fix "ignore unlock failures after withdraw" + - arm64: Remove unnecessary irqflags alternative.h include + - x86/boot/64: Clear most of CR4 in startup_64(), except PAE, MCE and LA57 + - selftests/bpf: Fix umount cgroup2 error in test_sockmap + - tcp: increase the default TCP scaling ratio + - cpufreq: exit() callback is optional + - x86/pat: Introduce lookup_address_in_pgd_attr() + - x86/pat: Restructure _lookup_address_cpa() + - x86/pat: Fix W^X violation false-positives when running as Xen PV guest + - udp: Avoid call to compute_score on multiple sites + - openrisc: traps: Don't send signals to kernel mode threads + - cppc_cpufreq: Fix possible null pointer dereference + - wifi: iwlwifi: mvm: init vif works only once + - scsi: libsas: Fix the failure of adding phy with zero-address to port + - scsi: hpsa: Fix allocation size for Scsi_Host private data + - x86/purgatory: Switch to the position-independent small code model + - wifi: ath12k: fix out-of-bound access of qmi_invoke_handler() + - thermal/drivers/mediatek/lvts_thermal: Add coeff for mt8192 + - thermal/drivers/tsens: Fix null pointer dereference + - dt-bindings: thermal: loongson,ls2k-thermal: Add Loongson-2K0500 compatible + - dt-bindings: thermal: loongson,ls2k-thermal: Fix incorrect compatible + definition + - wifi: ath10k: Fix an error code problem in + ath10k_dbg_sta_write_peer_debug_trigger() + - gfs2: Remove ill-placed consistency check + - gfs2: Fix potential glock use-after-free on unmount + - gfs2: finish_xmote cleanup + - gfs2: do_xmote fixes + - thermal/debugfs: Avoid excessive updates of trip point statistics + - selftests/bpf: Fix a fd leak in error paths in open_netns + - scsi: ufs: core: mcq: Fix ufshcd_mcq_sqe_search() + - cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations + - wifi: ath10k: populate board data for WCN3990 + - net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset + handlers + - net: dsa: mv88e6xxx: Avoid EEPROM timeout without EEPROM on 88E6250-family + switches + - tcp: avoid premature drops in tcp_add_backlog() + - thermal/debugfs: Create records for cdev states as they get used + - thermal/debugfs: Pass cooling device state to thermal_debug_cdev_add() + - pwm: sti: Prepare removing pwm_chip from driver data + - pwm: sti: Simplify probe function using devm functions + - drivers/perf: hisi_pcie: Fix out-of-bound access when valid event group + - drivers/perf: hisi: hns3: Fix out-of-bound access when valid event group + - drivers/perf: hisi: hns3: Actually use devm_add_action_or_reset() + - net: give more chances to rcu in netdev_wait_allrefs_any() + - macintosh/via-macii: Fix "BUG: sleeping function called from invalid + context" + - wifi: carl9170: add a proper sanity check for endpoints + - bpf: Fix verifier assumptions about socket->sk + - selftests/bpf: Run cgroup1_hierarchy test in own mount namespace + - wifi: ar5523: enable proper endpoint verification + - pwm: Drop useless member .of_pwm_n_cells of struct pwm_chip + - pwm: Let the of_xlate callbacks accept references without period + - pwm: Drop duplicate check against chip->npwm in of_pwm_xlate_with_flags() + - pwm: Reorder symbols in core.c + - pwm: Provide an inline function to get the parent device of a given chip + - pwm: meson: Change prototype of a few helpers to prepare further changes + - pwm: meson: Make use of pwmchip_parent() accessor + - pwm: meson: Add check for error from clk_round_rate() + - pwm: meson: Use mul_u64_u64_div_u64() for frequency calculating + - bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE + - sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe() + - Revert "sh: Handle calling csum_partial with misaligned data" + - wifi: mt76: mt7603: fix tx queue of loopback packets + - wifi: mt76: mt7603: add wpdma tx eof flag for PSE client reset + - wifi: mt76: mt7996: fix size of txpower MCU command + - wifi: mt76: mt7925: ensure 4-byte alignment for suspend & wow command + - wifi: mt76: mt7996: fix uninitialized variable in mt7996_irq_tasklet() + - wifi: mt76: mt7996: fix potential memory leakage when reading chip + temperature + - libbpf: Fix error message in attach_kprobe_multi + - wifi: nl80211: Avoid address calculations via out of bounds array indexing + - wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode + - selftests/binderfs: use the Makefile's rules, not Make's implicit rules + - selftests/resctrl: fix clang build failure: use LOCAL_HDRS + - selftests: default to host arch for LLVM builds + - kunit: Fix kthread reference + - kunit: unregister the device on error + - kunit: bail out early in __kunit_test_suites_init() if there are no suites + to test + - selftests/bpf: Fix pointer arithmetic in test_xdp_do_redirect + - HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors + - scsi: bfa: Ensure the copied buf is NUL terminated + - scsi: qedf: Ensure the copied buf is NUL terminated + - scsi: qla2xxx: Fix debugfs output for fw_resource_count + - gpio: nuvoton: Fix sgpio irq handle error + - x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks() + - wifi: mwl8k: initialize cmd->addr[] properly + - HID: amd_sfh: Handle "no sensors" in PM operations + - usb: aqc111: stop lying about skb->truesize + - net: usb: sr9700: stop lying about skb->truesize + - m68k: Fix spinlock race in kernel thread creation + - m68k: mac: Fix reboot hang on Mac IIci + - dm-delay: fix workqueue delay_timer race + - dm-delay: fix hung task introduced by kthread mode + - dm-delay: fix max_delay calculations + - ptp: ocp: fix DPLL functions + - net: ipv6: fix wrong start position when receive hop-by-hop fragment + - eth: sungem: remove .ndo_poll_controller to avoid deadlocks + - selftests: net: add missing config for amt.sh + - selftests: net: move amt to socat for better compatibility + - net: ethernet: mediatek: split tx and rx fields in mtk_soc_data struct + - net: ethernet: mediatek: use ADMAv1 instead of ADMAv2.0 on MT7981 and MT7986 + - ice: Fix package download algorithm + - net: ethernet: cortina: Locking fixes + - af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg + - net: usb: smsc95xx: stop lying about skb->truesize + - net: openvswitch: fix overwriting ct original tuple for ICMPv6 + - ipv6: sr: add missing seg6_local_exit + - ipv6: sr: fix incorrect unregister order + - ipv6: sr: fix invalid unregister error path + - net/mlx5: Fix peer devlink set for SF representor devlink port + - net/mlx5: Reload only IB representors upon lag disable/enable + - net/mlx5: Add a timeout to acquire the command queue semaphore + - net/mlx5: Discard command completions in internal error + - s390/bpf: Emit a barrier for BPF_FETCH instructions + - riscv, bpf: make some atomic operations fully ordered + - ax25: Use kernel universal linked list to implement ax25_dev_list + - ax25: Fix reference count leak issues of ax25_dev + - ax25: Fix reference count leak issue of net_device + - dpll: fix return value check for kmemdup + - net: fec: remove .ndo_poll_controller to avoid deadlocks + - mptcp: SO_KEEPALIVE: fix getsockopt support + - mptcp: cleanup writer wake-up + - mptcp: avoid some duplicate code in socket option handling + - mptcp: implement TCP_NOTSENT_LOWAT support + - mptcp: cleanup SOL_TCP handling + - mptcp: fix full TCP keep-alive support + - net: stmmac: Offload queueMaxSDU from tc-taprio + - net: stmmac: est: Per Tx-queue error count for HLBF + - net: stmmac: Report taprio offload status + - net: stmmac: move the EST lock to struct stmmac_priv + - net: micrel: Fix receiving the timestamp in the frame for lan8841 + - Bluetooth: compute LE flow credits based on recvbuf space + - Bluetooth: qca: Fix error code in qca_read_fw_build_info() + - Bluetooth: ISO: Add hcon for listening bis sk + - Bluetooth: ISO: Clean up returns values in iso_connect_ind() + - Bluetooth: ISO: Make iso_get_sock_listen generic + - Bluetooth: Remove usage of the deprecated ida_simple_xx() API + - Bluetooth: hci_event: Remove code to removed CONFIG_BT_HS + - Bluetooth: HCI: Remove HCI_AMP support + - ice: make ice_vsi_cfg_rxq() static + - ice: make ice_vsi_cfg_txq() static + - overflow: Change DEFINE_FLEX to take __counted_by member + - Bluetooth: hci_conn, hci_sync: Use __counted_by() to avoid -Wfamnae warnings + - Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1 + - drm/bridge: Fix improper bridge init order with pre_enable_prev_first + - drm/ci: update device type for volteer devices + - drm/nouveau/dp: Fix incorrect return code in r535_dp_aux_xfer() + - drm/omapdrm: Fix console by implementing fb_dirty + - drm/omapdrm: Fix console with deferred ops + - printk: Let no_printk() use _printk() + - dev_printk: Add and use dev_no_printk() + - drm/lcdif: Do not disable clocks on already suspended hardware + - drm/dp: Don't attempt AUX transfers when eDP panels are not powered + - drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't + assert + - drm/amd/display: Fix potential index out of bounds in color transformation + function + - drm/amd/display: Remove redundant condition in dcn35_calc_blocks_to_gate() + - ASoC: Intel: Disable route checks for Skylake boards + - ASoC: Intel: avs: ssm4567: Do not ignore route checks + - mtd: core: Report error if first mtd_otp_size() call fails in + mtd_otp_nvmem_add() + - mtd: rawnand: hynix: fixed typo + - drm/imagination: avoid -Woverflow warning + - ASoC: mediatek: Assign dummy when codec not specified for a DAI link + - drm/panel: ltk050h3146w: add MIPI_DSI_MODE_VIDEO to LTK050H3148W flags + - drm/panel: ltk050h3146w: drop duplicate commands from LTK050H3148W init + - fbdev: shmobile: fix snprintf truncation + - ASoC: kirkwood: Fix potential NULL dereference + - drm/meson: vclk: fix calculation of 59.94 fractional rates + - drm/mediatek: Add 0 size check to mtk_drm_gem_obj + - drm/mediatek: Init `ddp_comp` with devm_kcalloc() + - ASoC: SOF: Intel: hda-dai: fix channel map configuration for aggregated + dailink + - powerpc/fsl-soc: hide unused const variable + - ASoC: SOF: Intel: mtl: Correct rom_status_reg + - ASoC: SOF: Intel: lnl: Correct rom_status_reg + - ASoC: SOF: Intel: mtl: Disable interrupts when firmware boot failed + - ASoC: SOF: Intel: mtl: Implement firmware boot state check + - fbdev: sisfb: hide unused variables + - selftests: cgroup: skip test_cgcore_lesser_ns_open when cgroup2 mounted + without nsdelegate + - ASoC: Intel: avs: Restore stream decoupling on prepare + - ASoC: Intel: avs: Fix ASRC module initialization + - ASoC: Intel: avs: Fix potential integer overflow + - ASoC: Intel: avs: Test result of avs_get_module_entry() + - media: ngene: Add dvb_ca_en50221_init return value check + - staging: media: starfive: Remove links when unregistering devices + - media: rcar-vin: work around -Wenum-compare-conditional warning + - media: radio-shark2: Avoid led_names truncations + - drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference + - platform/x86: xiaomi-wmi: Fix race condition when reporting key events + - drm/msm/dp: allow voltage swing / pre emphasis of 3 + - drm/msm/dp: Avoid a long timeout for AUX transfer if nothing connected + - media: ipu3-cio2: Request IRQ earlier + - media: dt-bindings: ovti,ov2680: Fix the power supply names + - media: i2c: et8ek8: Don't strip remove function when driver is builtin + - media: v4l2-subdev: Fix stream handling for crop API + - fbdev: sh7760fb: allow modular build + - media: atomisp: ssh_css: Fix a null-pointer dereference in + load_video_binaries + - drm/arm/malidp: fix a possible null pointer dereference + - drm: vc4: Fix possible null pointer dereference + - ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value + - drm/bridge: anx7625: Don't log an error when DSI host can't be found + - drm/bridge: icn6211: Don't log an error when DSI host can't be found + - drm/bridge: lt8912b: Don't log an error when DSI host can't be found + - drm/bridge: lt9611: Don't log an error when DSI host can't be found + - drm/bridge: lt9611uxc: Don't log an error when DSI host can't be found + - drm/bridge: tc358775: Don't log an error when DSI host can't be found + - drm/bridge: dpc3433: Don't log an error when DSI host can't be found + - drm/panel: novatek-nt35950: Don't log an error when DSI host can't be found + - drm/bridge: anx7625: Update audio status while detecting + - drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector + - ALSA: hda: cs35l41: Remove Speaker ID for Lenovo Legion slim 7 16ARHA7 + - drm/mipi-dsi: use correct return type for the DSC functions + - media: uvcvideo: Add quirk for Logitech Rally Bar + - drm/rockchip: vop2: Do not divide height twice for YUV + - drm/edid: Parse topology block for all DispID structure v1.x + - media: cadence: csi2rx: configure DPHY before starting source stream + - clk: samsung: exynosautov9: fix wrong pll clock id value + - RDMA/mlx5: Uncacheable mkey has neither rb_key or cache_ent + - RDMA/mlx5: Change check for cacheable mkeys + - RDMA/mlx5: Adding remote atomic access flag to updatable flags + - clk: mediatek: pllfh: Don't log error for missing fhctl node + - iommu: Undo pasid attachment only for the devices that have succeeded + - RDMA/hns: Fix return value in hns_roce_map_mr_sg + - RDMA/hns: Fix deadlock on SRQ async events. + - RDMA/hns: Fix UAF for cq async event + - RDMA/hns: Fix GMV table pagesize + - RDMA/hns: Use complete parentheses in macros + - RDMA/hns: Modify the print level of CQE error + - clk: mediatek: mt8365-mm: fix DPI0 parent + - clk: rs9: fix wrong default value for clock amplitude + - clk: qcom: clk-alpha-pll: remove invalid Stromer register offset + - RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt + - RDMA/rxe: Allow good work requests to be executed + - RDMA/rxe: Fix incorrect rxe_put in error path + - IB/mlx5: Use __iowrite64_copy() for write combining stores + - clk: renesas: r8a779a0: Fix CANFD parent clock + - clk: renesas: r9a07g043: Add clock and reset entry for PLIC + - lib/test_hmm.c: handle src_pfns and dst_pfns allocation failure + - mm/ksm: fix ksm exec support for prctl + - clk: qcom: dispcc-sm8450: fix DisplayPort clocks + - clk: qcom: dispcc-sm6350: fix DisplayPort clocks + - clk: qcom: dispcc-sm8550: fix DisplayPort clocks + - clk: qcom: dispcc-sm8650: fix DisplayPort clocks + - clk: qcom: mmcc-msm8998: fix venus clock issue + - x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map + - x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS + - ext4: avoid excessive credit estimate in ext4_tmpfile() + - RDMA/mana_ib: Introduce helpers to create and destroy mana queues + - RDMA/mana_ib: Use struct mana_ib_queue for CQs + - RDMA/mana_ib: boundary check before installing cq callbacks + - virt: acrn: stop using follow_pfn + - drivers/virt/acrn: fix PFNMAP PTE checks in acrn_vm_ram_map() + - sunrpc: removed redundant procp check + - nfsd: don't create nfsv4recoverydir in nfsdfs when not used. + - ext4: fix potential unnitialized variable + - ext4: remove the redundant folio_wait_stable() + - clk: qcom: Fix SC_CAMCC_8280XP dependencies + - [Config] updateconfigs for SC_CAMCC_8280XP + - clk: qcom: Fix SM_GPUCC_8650 dependencies + - [Config] updateconfigs for SM_GPUCC_8650 + - clk: qcom: apss-ipq-pll: fix PLL rate for IPQ5018 + - of: module: add buffer overflow check in of_modalias() + - bnxt_re: avoid shift undefined behavior in bnxt_qplib_alloc_init_hwq + - SUNRPC: Fix gss_free_in_token_pages() + - selftests/damon/_damon_sysfs: check errors from nr_schemes file reads + - selftests/kcmp: remove unused open mode + - RDMA/IPoIB: Fix format truncation compilation errors + - RDMA/cma: Fix kmemleak in rdma_core observed during blktests nvme/rdma use + siw + - samples/landlock: Fix incorrect free in populate_ruleset_net + - tracing/user_events: Prepare find/delete for same name events + - tracing/user_events: Fix non-spaced field matching + - modules: Drop the .export_symbol section from the final modules + - net: bridge: xmit: make sure we have at least eth header len bytes + - selftests: net: bridge: increase IGMP/MLD exclude timeout membership + interval + - net: bridge: mst: fix vlan use-after-free + - net: qrtr: ns: Fix module refcnt + - selftests/net/lib: no need to record ns name if it already exist + - idpf: don't skip over ethtool tcp-data-split setting + - netrom: fix possible dead-lock in nr_rt_ioctl() + - af_packet: do not call packet_read_pending() from tpacket_destruct_skb() + - sched/fair: Allow disabling sched_balance_newidle with + sched_relax_domain_level + - sched/core: Fix incorrect initialization of the 'burst' parameter in + cpu_max_write() + - net: wangxun: fix to change Rx features + - net: wangxun: match VLAN CTAG and STAG features + - net: txgbe: move interrupt codes to a separate file + - net: txgbe: use irq_domain for interrupt controller + - net: txgbe: fix to control VLAN strip + - l2tp: fix ICMP error handling for UDP-encap sockets + - io_uring/net: ensure async prep handlers always initialize ->done_io + - pwm: Fix setting period with #pwm-cells = <1> and of_pwm_single_xlate() + - net: txgbe: fix to clear interrupt status after handling IRQ + - net: txgbe: fix GPIO interrupt blocking + - Linux 6.8.12 + + * Noble update: v6.8.11 upstream stable release (LP: #2070355) + - drm/amd/display: Fix division by zero in setup_dsc_config + - net: ks8851: Fix another TX stall caused by wrong ISR flag handling + - ice: pass VSI pointer into ice_vc_isvalid_q_id + - ice: remove unnecessary duplicate checks for VF VSI ID + - Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect() + - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() + - KEYS: trusted: Fix memory leak in tpm2_key_encode() + - erofs: get rid of erofs_fs_context + - erofs: reliably distinguish block based and fscache mode + - binder: fix max_thread type inconsistency + - usb: dwc3: Wait unconditionally after issuing EndXfer command + - net: usb: ax88179_178a: fix link status when link is set to down/up + - usb: typec: ucsi: displayport: Fix potential deadlock + - usb: typec: tipd: fix event checking for tps25750 + - usb: typec: tipd: fix event checking for tps6598x + - serial: kgdboc: Fix NMI-safety problems from keyboard reset code + - remoteproc: mediatek: Make sure IPI buffer fits in L2TCM + - KEYS: trusted: Do not use WARN when encode fails + - admin-guide/hw-vuln/core-scheduling: fix return type of PR_SCHED_CORE_GET + - docs: kernel_include.py: Cope with docutils 0.21 + - Docs/admin-guide/mm/damon/usage: fix wrong example of DAMOS filter matching + sysfs file + - block: add a disk_has_partscan helper + - block: add a partscan sysfs attribute for disks + - Linux 6.8.11 + + * Noble update: v6.8.10 upstream stable release (LP: #2070349) + - rust: module: place generated init_module() function in .init.text + - rust: macros: fix soundness issue in `module!` macro + - wifi: nl80211: don't free NULL coalescing rule + - pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T + - pinctrl/meson: fix typo in PDM's pin name + - pinctrl: core: delete incorrect free in pinctrl_enable() + - pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback + - pinctrl: mediatek: paris: Rework support for + PIN_CONFIG_{INPUT,OUTPUT}_ENABLE + - sunrpc: add a struct rpc_stats arg to rpc_create_args + - nfs: expose /proc/net/sunrpc/nfs in net namespaces + - nfs: make the rpc_stat per net namespace + - nfs: Handle error of rpc_proc_register() in nfs_net_init(). + - pinctrl: baytrail: Fix selecting gpio pinctrl state + - power: rt9455: hide unused rt9455_boost_voltage_values + - power: supply: mt6360_charger: Fix of_match for usb-otg-vbus regulator + - pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map() + - nfsd: rename NFSD_NET_* to NFSD_STATS_* + - nfsd: expose /proc/net/sunrpc/nfsd in net namespaces + - nfsd: make all of the nfsd stats per-network namespace + - NFSD: add support for CB_GETATTR callback + - NFSD: Fix nfsd4_encode_fattr4() crasher + - regulator: mt6360: De-capitalize devicetree regulator subnodes + - regulator: change stubbed devm_regulator_get_enable to return Ok + - regulator: change devm_regulator_get_enable_optional() stub to return Ok + - bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition + - bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue + - regmap: Add regmap_read_bypassed() + - ASoC: SOF: Intel: add default firmware library path for LNL + - nvme: fix warn output about shared namespaces without CONFIG_NVME_MULTIPATH + - bpf: Fix a verifier verbose message + - spi: axi-spi-engine: use common AXI macros + - spi: axi-spi-engine: fix version format string + - spi: hisi-kunpeng: Delete the dump interface of data registers in debugfs + - bpf, arm64: Fix incorrect runtime stats + - riscv, bpf: Fix incorrect runtime stats + - ASoC: Intel: avs: Set name of control as in topology + - ASoC: codecs: wsa881x: set clk_stop_mode1 flag + - s390/mm: Fix storage key clearing for guest huge pages + - s390/mm: Fix clearing storage keys for huge pages + - arm32, bpf: Reimplement sign-extension mov instruction + - xdp: use flags field to disambiguate broadcast redirect + - efi/unaccepted: touch soft lockup during memory accept + - ice: ensure the copied buf is NUL terminated + - bna: ensure the copied buf is NUL terminated + - octeontx2-af: avoid off-by-one read from userspace + - thermal/debugfs: Free all thermal zone debug memory on zone removal + - thermal/debugfs: Fix two locking issues with thermal zone debug + - nsh: Restore skb->{protocol,data,mac_header} for outer header in + nsh_gso_segment(). + - net l2tp: drop flow hash on forward + - thermal/debugfs: Prevent use-after-free from occurring after cdev removal + - s390/vdso: Add CFI for RA register to asm macro vdso_func + - Fix a potential infinite loop in extract_user_to_sg() + - ALSA: emu10k1: fix E-MU card dock presence monitoring + - ALSA: emu10k1: factor out snd_emu1010_load_dock_firmware() + - ALSA: emu10k1: move the whole GPIO event handling to the workqueue + - ALSA: emu10k1: fix E-MU dock initialization + - net: qede: sanitize 'rc' in qede_add_tc_flower_fltr() + - net: qede: use return from qede_parse_flow_attr() for flower + - net: qede: use return from qede_parse_flow_attr() for flow_spec + - net: qede: use return from qede_parse_actions() + - vxlan: Fix racy device stats updates. + - vxlan: Add missing VNI filter counter update in arp_reduce(). + - ASoC: meson: axg-fifo: use FIELD helpers + - ASoC: meson: axg-fifo: use threaded irq to check periods + - ASoC: meson: axg-card: make links nonatomic + - ASoC: meson: axg-tdm-interface: manage formatters in trigger + - ASoC: meson: cards: select SND_DYNAMIC_MINORS + - ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node() + - s390/cio: Ensure the copied buf is NUL terminated + - cxgb4: Properly lock TX queue for the selftest. + - net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341 + - drm/amdgpu: fix doorbell regression + - spi: fix null pointer dereference within spi_sync + - net: bridge: fix multicast-to-unicast with fraglist GSO + - net: core: reject skb_copy(_expand) for fraglist GSO skbs + - rxrpc: Clients must accept conn from any address + - tipc: fix a possible memleak in tipc_buf_append + - vxlan: Pull inner IP header in vxlan_rcv(). + - s390/qeth: Fix kernel panic after setting hsuid + - drm/panel: ili9341: Correct use of device property APIs + - [Config] updateconfigs for DRM_PANEL_ILITEK_ILI9341 + - drm/panel: ili9341: Respect deferred probe + - drm/panel: ili9341: Use predefined error codes + - ipv4: Fix uninit-value access in __ip_make_skb() + - net: gro: fix udp bad offset in socket lookup by adding + {inner_}network_offset to napi_gro_cb + - net: gro: add flush check in udp_gro_receive_segment + - drm/xe/display: Fix ADL-N detection + - clk: qcom: smd-rpm: Restore msm8976 num_clk + - clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change + - powerpc/pseries: make max polling consistent for longer H_CALLs + - powerpc/pseries/iommu: LPAR panics during boot up with a frozen PE + - EDAC/versal: Do not log total error counts + - swiotlb: initialise restricted pool list_head when SWIOTLB_DYNAMIC=y + - KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr() + - exfat: fix timing of synchronizing bitmap and inode + - firmware: microchip: don't unconditionally print validation success + - scsi: ufs: core: Fix MCQ MAC configuration + - scsi: lpfc: Move NPIV's transport unregistration to after resource clean up + - scsi: lpfc: Remove IRQF_ONESHOT flag from threaded IRQ handling + - scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic + - scsi: lpfc: Replace hbalock with ndlp lock in lpfc_nvme_unregister_port() + - scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up() + - scsi: lpfc: Use a dedicated lock for ras_fwlog state + - gfs2: Fix invalid metadata access in punch_hole + - fs/9p: fix uninitialized values during inode evict + - wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc + - wifi: cfg80211: fix rdev_dump_mpp() arguments order + - wifi: mac80211: fix prep_connection error path + - wifi: iwlwifi: read txq->read_ptr under lock + - wifi: iwlwifi: mvm: guard against invalid STA ID on removal + - net: mark racy access on sk->sk_rcvbuf + - drm/xe: Fix END redefinition + - scsi: mpi3mr: Avoid memcpy field-spanning write WARNING + - scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload + - btrfs: return accurate error code on open failure in open_fs_devices() + - drm/amdkfd: Check cgroup when returning DMABuf info + - drm/amdkfd: range check cp bad op exception interrupts + - bpf: Check bloom filter map value size + - selftests/ftrace: Fix event filter target_func selection + - kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries + - ASoC: SOF: Intel: hda-dsp: Skip IMR boot on ACE platforms in case of S3 + suspend + - regulator: tps65132: Add of_match table + - OSS: dmasound/paula: Mark driver struct with __refdata to prevent section + mismatch + - scsi: ufs: core: WLUN suspend dev/link state error recovery + - scsi: libsas: Align SMP request allocation to ARCH_DMA_MINALIGN + - scsi: ufs: core: Fix MCQ mode dev command timeout + - ALSA: line6: Zero-initialize message buffers + - block: fix overflow in blk_ioctl_discard() + - ASoC: codecs: ES8326: Solve error interruption issue + - ASoC: codecs: ES8326: modify clock table + - net: bcmgenet: Reset RBUF on first open + - vboxsf: explicitly deny setlease attempts + - ata: sata_gemini: Check clk_enable() result + - firewire: ohci: mask bus reset interrupts between ISR and bottom half + - tools/power turbostat: Fix added raw MSR output + - tools/power turbostat: Increase the limit for fd opened + - tools/power turbostat: Fix Bzy_MHz documentation typo + - tools/power turbostat: Do not print negative LPI residency + - tools/power turbostat: Expand probe_intel_uncore_frequency() + - tools/power turbostat: Print ucode revision only if valid + - tools/power turbostat: Fix warning upon failed /dev/cpu_dma_latency read + - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve + - btrfs: always clear PERTRANS metadata during commit + - memblock tests: fix undefined reference to `early_pfn_to_nid' + - memblock tests: fix undefined reference to `panic' + - memblock tests: fix undefined reference to `BIT' + - nouveau/gsp: Avoid addressing beyond end of rpc->entries + - scsi: target: Fix SELinux error when systemd-modules loads the target module + - scsi: hisi_sas: Handle the NCQ error returned by D2H frame + - blk-iocost: avoid out of bounds shift + - accel/ivpu: Remove d3hot_after_power_off WA + - accel/ivpu: Improve clarity of MMU error messages + - accel/ivpu: Fix missed error message after VPU rename + - platform/x86: acer-wmi: Add support for Acer PH18-71 + - gpu: host1x: Do not setup DMA for virtual devices + - MIPS: scall: Save thread_info.syscall unconditionally on entry + - tools/power/turbostat: Fix uncore frequency file string + - net: add copy_safe_from_sockptr() helper + - nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies + - drm/amdgpu: Refine IB schedule error logging + - drm/amd/display: add DCN 351 version for microcode load + - drm/amdgpu: add smu 14.0.1 discovery support + - drm/amdgpu: implement IRQ_STATE_ENABLE for SDMA v4.4.2 + - drm/amd/display: Skip on writeback when it's not applicable + - drm/amd/pm: fix the high voltage issue after unload + - drm/amdgpu: Fix VCN allocation in CPX partition + - amd/amdkfd: sync all devices to wait all processes being evicted + - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior + - Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails + - Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl + - hv_netvsc: Don't free decrypted memory + - uio_hv_generic: Don't free decrypted memory + - Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted + - drm/xe/xe_migrate: Cast to output precision before multiplying operands + - drm/xe: Label RING_CONTEXT_CONTROL as masked + - smb3: fix broken reconnect when password changing on the server by allowing + password rotation + - iommu: mtk: fix module autoloading + - fs/9p: only translate RWX permissions for plain 9P2000 + - fs/9p: translate O_TRUNC into OTRUNC + - fs/9p: fix the cache always being enabled on files with qid flags + - 9p: explicitly deny setlease attempts + - powerpc/crypto/chacha-p10: Fix failure on non Power10 + - gpio: wcove: Use -ENOTSUPP consistently + - gpio: crystalcove: Use -ENOTSUPP consistently + - clk: Don't hold prepare_lock when calling kref_put() + - fs/9p: remove erroneous nlink init from legacy stat2inode + - fs/9p: drop inodes immediately on non-.L too + - gpio: lpc32xx: fix module autoloading + - drm/nouveau/dp: Don't probe eDP ports twice harder + - platform/x86/amd: pmf: Decrease error message to debug + - platform/x86: ISST: Add Granite Rapids-D to HPM CPU list + - drm/radeon: silence UBSAN warning (v3) + - net:usb:qmi_wwan: support Rolling modules + - blk-iocost: do not WARN if iocg was already offlined + - SUNRPC: add a missing rpc_stat for TCP TLS + - qibfs: fix dentry leak + - xfrm: Preserve vlan tags for transport mode software GRO + - ARM: 9381/1: kasan: clear stale stack poison + - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets + - tcp: Use refcount_inc_not_zero() in tcp_twsk_unique(). + - Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout + - Bluetooth: msft: fix slab-use-after-free in msft_do_close() + - arm64: dts: mediatek: mt8183-pico6: Fix bluetooth node + - Bluetooth: HCI: Fix potential null-ptr-deref + - Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout + - net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs + - rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation + - hwmon: (corsair-cpro) Use a separate buffer for sending commands + - hwmon: (corsair-cpro) Use complete_all() instead of complete() in + ccp_raw_event() + - hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock + - phonet: fix rtm_phonet_notify() skb allocation + - netlink: specs: Add missing bridge linkinfo attrs + - nfc: nci: Fix kcov check in nci_rx_work() + - net: bridge: fix corrupted ethernet header on multicast-to-unicast + - ipv6: Fix potential uninit-value access in __ip6_make_skb() + - selftests: test_bridge_neigh_suppress.sh: Fix failures due to duplicate MAC + - rxrpc: Fix the names of the fields in the ACK trailer struct + - rxrpc: Fix congestion control algorithm + - rxrpc: Only transmit one ACK per jumbo packet received + - dt-bindings: net: mediatek: remove wrongly added clocks and SerDes + - ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action() + - net-sysfs: convert dev->operstate reads to lockless ones + - hsr: Simplify code for announcing HSR nodes timer setup + - ipv6: annotate data-races around cnf.disable_ipv6 + - ipv6: prevent NULL dereference in ip6_output() + - net/smc: fix neighbour and rtable leak in smc_ib_find_route() + - net: hns3: using user configure after hardware reset + - net: hns3: direct return when receive a unknown mailbox message + - net: hns3: change type of numa_node_mask as nodemask_t + - net: hns3: release PTP resources if pf initialization failed + - net: hns3: use appropriate barrier function after setting a bit value + - net: hns3: fix port vlan filter not disabled issue + - net: hns3: fix kernel crash when devlink reload during initialization + - net: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family + - drm/meson: dw-hdmi: power up phy on device init + - drm/meson: dw-hdmi: add bandgap setting for g12 + - drm/connector: Add \n to message about demoting connector force-probes + - dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11 + users + - gpiolib: cdev: Fix use after free in lineinfo_changed_notify + - gpiolib: cdev: fix uninitialised kfifo + - drm/amdgpu: Fix comparison in amdgpu_res_cpu_visible + - drm/amdgpu: once more fix the call oder in amdgpu_ttm_move() v2 + - firewire: nosy: ensure user_length is taken into account when fetching + packet contents + - Reapply "drm/qxl: simplify qxl_fence_wait" + - usb: typec: ucsi: Check for notifications after init + - usb: typec: ucsi: Fix connector check on init + - usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed + device + - usb: ohci: Prevent missed ohci interrupts + - USB: core: Fix access violation during port device removal + - usb: gadget: composite: fix OS descriptors w_value logic + - usb: gadget: uvc: use correct buffer size when parsing configfs lists + - usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete + - usb: gadget: f_fs: Fix a race condition when processing setup packets. + - usb: xhci-plat: Don't include xhci.h + - usb: dwc3: core: Prevent phy suspend during init + - usb: typec: tcpm: clear pd_event queue in PORT_RESET + - usb: typec: tcpm: unregister existing source caps before re-registration + - usb: typec: tcpm: Check for port partner validity before consuming it + - ALSA: hda/realtek: Fix mute led of HP Laptop 15-da3001TU + - ALSA: hda/realtek: Fix conflicting PCI SSID 17aa:386f for Lenovo Legion + models + - firewire: ohci: fulfill timestamp for some local asynchronous transaction + - mm/slub: avoid zeroing outside-object freepointer for single free + - btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks() + - btrfs: set correct ram_bytes when splitting ordered extent + - btrfs: qgroup: do not check qgroup inherit if qgroup is disabled + - btrfs: make sure that WRITTEN is set on all metadata blocks + - maple_tree: fix mas_empty_area_rev() null pointer dereference + - mm/slab: make __free(kfree) accept error pointers + - mptcp: ensure snd_nxt is properly initialized on connect + - mptcp: only allow set existing scheduler for net.mptcp.scheduler + - workqueue: Fix selection of wake_cpu in kick_pool() + - dt-bindings: iio: health: maxim,max30102: fix compatible check + - iio:imu: adis16475: Fix sync mode setting + - iio: pressure: Fixes BME280 SPI driver data + - iio: pressure: Fixes SPI support for BMP3xx devices + - iio: accel: mxc4005: Interrupt handling fixes + - iio: accel: mxc4005: Reset chip on probe() and resume() + - kmsan: compiler_types: declare __no_sanitize_or_inline + - e1000e: change usleep_range to udelay in PHY mdic access + - tipc: fix UAF in error path + - xtensa: fix MAKE_PC_FROM_RA second argument + - net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access + - net: bcmgenet: synchronize use of bcmgenet_set_rx_mode() + - net: bcmgenet: synchronize UMAC_CMD access + - ASoC: tegra: Fix DSPK 16-bit playback + - ASoC: ti: davinci-mcasp: Fix race condition during probe + - dyndbg: fix old BUG_ON in >control parser + - slimbus: qcom-ngd-ctrl: Add timeout for wait operation + - clk: samsung: Revert "clk: Use device_get_match_data()" + - clk: sunxi-ng: common: Support minimum and maximum rate + - clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI + - mei: me: add lunar lake point M DID + - drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor() + - Revert "drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()" + - drm/amdkfd: don't allow mapping the MMIO HDP page with large pages + - drm/ttm: Print the memory decryption status just once + - drm/vmwgfx: Fix Legacy Display Unit + - drm/vmwgfx: Fix invalid reads in fence signaled events + - drm/imagination: Ensure PVR_MIPS_PT_PAGE_COUNT is never zero + - drm/amd/display: Fix idle optimization checks for multi-display and dual eDP + - drm/nouveau/gsp: Use the sg allocator for level 2 of radix3 + - drm/i915/gt: Automate CCS Mode setting during engine resets + - drm/i915/bios: Fix parsing backlight BDB data + - drm/amd/display: Handle Y carry-over in VCP X.Y calculation + - drm/amd/display: Fix incorrect DSC instance for MST + - arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration + - iommu/arm-smmu: Use the correct type in nvidia_smmu_context_fault() + - net: fix out-of-bounds access in ops_init + - hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us + - misc/pvpanic-pci: register attributes via pci_driver + - x86/apic: Don't access the APIC when disabling x2APIC + - selftests/mm: fix powerpc ARCH check + - mm: use memalloc_nofs_save() in page_cache_ra_order() + - mm/userfaultfd: reset ptes when close() for wr-protected ones + - iommu/amd: Enhance def_domain_type to handle untrusted device + - fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan + - fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry() + - nvme-pci: Add quirk for broken MSIs + - regulator: core: fix debugfs creation regression + - spi: microchip-core-qspi: fix setting spi bus clock rate + - ksmbd: off ipv6only for both ipv4/ipv6 binding + - ksmbd: avoid to send duplicate lease break notifications + - ksmbd: do not grant v2 lease if parent lease key and epoch are not set + - tracefs: Reset permissions on remount if permissions are options + - tracefs: Still use mount point as default permissions for instances + - eventfs: Do not treat events directory different than other directories + - Bluetooth: qca: fix invalid device address check + - Bluetooth: qca: fix wcn3991 device address check + - Bluetooth: qca: add missing firmware sanity checks + - Bluetooth: qca: fix NVM configuration parsing + - Bluetooth: qca: generalise device address check + - Bluetooth: qca: fix info leak when fetching board id + - Bluetooth: qca: fix info leak when fetching fw build id + - Bluetooth: qca: fix firmware check error path + - keys: Fix overwrite of key expiration on instantiation + - Linux 6.8.10 + + * Noble update: v6.8.9 upstream stable release (LP: #2070337) + - cifs: Fix reacquisition of volume cookie on still-live connection + - smb: client: fix rename(2) regression against samba + - cifs: reinstate original behavior again for forceuid/forcegid + - HID: intel-ish-hid: ipc: Fix dev_err usage with uninitialized dev->devc + - HID: logitech-dj: allow mice to use all types of reports + - arm64: dts: rockchip: set PHY address of MT7531 switch to 0x1f + - arm64: dts: rockchip: enable internal pull-up on Q7_USB_ID for RK3399 Puma + - arm64: dts: rockchip: fix alphabetical ordering RK3399 puma + - arm64: dts: rockchip: enable internal pull-up on PCIE_WAKE# for RK3399 Puma + - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi CM5 + - arm64: dts: rockchip: Remove unsupported node from the Pinebook Pro dts + - arm64: dts: mediatek: mt8183: Add power-domains properity to mfgcfg + - arm64: dts: mediatek: mt8192: Add missing gce-client-reg to mutex + - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to vpp/vdosys + - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex + - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex1 + - arm64: dts: mediatek: cherry: Describe CPU supplies + - arm64: dts: mediatek: mt8192-asurada: Update min voltage constraint for + MT6315 + - arm64: dts: mediatek: mt8195-cherry: Update min voltage constraint for + MT6315 + - arm64: dts: mediatek: mt8183-kukui: Use default min voltage for MT6358 + - arm64: dts: mediatek: mt7622: fix clock controllers + - arm64: dts: mediatek: mt7622: fix IR nodename + - arm64: dts: mediatek: mt7622: fix ethernet controller "compatible" + - arm64: dts: mediatek: mt7622: drop "reset-names" from thermal block + - arm64: dts: mediatek: mt7986: reorder properties + - arm64: dts: mediatek: mt7986: drop invalid properties from ethsys + - arm64: dts: mediatek: mt7986: drop "#reset-cells" from Ethernet controller + - arm64: dts: mediatek: mt7986: reorder nodes + - arm64: dts: mediatek: mt7986: drop invalid thermal block clock + - arm64: dts: mediatek: mt7986: prefix BPI-R3 cooling maps with "map-" + - arm64: dts: mediatek: mt2712: fix validation errors + - arm64: dts: rockchip: mark system power controller and fix typo on + orangepi-5-plus + - arm64: dts: rockchip: regulator for sd needs to be always on for BPI-R2Pro + - block: fix module reference leakage from bdev_open_by_dev error path + - arm64: dts: qcom: Fix type of "wdog" IRQs for remoteprocs + - arm64: dts: qcom: x1e80100: Fix the compatible for cluster idle states + - arm64: dts: qcom: sc8180x: Fix ss_phy_irq for secondary USB controller + - gpio: tangier: Use correct type for the IRQ chip data + - ARC: [plat-hsdk]: Remove misplaced interrupt-cells property + - wifi: mac80211: clean up assignments to pointer cache. + - wifi: mac80211: split mesh fast tx cache into local/proxied/forwarded + - wifi: iwlwifi: mvm: remove old PASN station when adding a new one + - wifi: iwlwifi: mvm: return uid from iwl_mvm_build_scan_cmd + - drm/gma500: Remove lid code + - wifi: mac80211_hwsim: init peer measurement result + - wifi: mac80211: remove link before AP + - wifi: mac80211: fix unaligned le16 access + - net: libwx: fix alloc msix vectors failed + - vxlan: drop packets from invalid src-address + - net: bcmasp: fix memory leak when bringing down interface + - mlxsw: core: Unregister EMAD trap using FORWARD action + - mlxsw: core_env: Fix driver initialization with old firmware + - mlxsw: pci: Fix driver initialization with old firmware + - ARM: dts: microchip: at91-sama7g5ek: Replace regulator-suspend-voltage with + the valid property + - icmp: prevent possible NULL dereferences from icmp_build_probe() + - bridge/br_netlink.c: no need to return void function + - bnxt_en: refactor reset close code + - bnxt_en: Fix the PCI-AER routines + - bnxt_en: Fix error recovery for 5760X (P7) chips + - cxl/core: Fix potential payload size confusion in cxl_mem_get_poison() + - net: dsa: mv88e6xx: fix supported_interfaces setup in + mv88e6250_phylink_get_caps() + - NFC: trf7970a: disable all regulators on removal + - netfs: Fix writethrough-mode error handling + - ax25: Fix netdev refcount issue + - soc: mediatek: mtk-svs: Append "-thermal" to thermal zone names + - tools: ynl: don't ignore errors in NLMSG_DONE messages + - net: usb: ax88179_178a: stop lying about skb->truesize + - tcp: Fix Use-After-Free in tcp_ao_connect_init + - net: gtp: Fix Use-After-Free in gtp_dellink + - net: phy: mediatek-ge-soc: follow netdev LED trigger semantics + - gpio: tegra186: Fix tegra186_gpio_is_accessible() check + - drm/xe: Remove sysfs only once on action add failure + - drm/xe: call free_gsc_pkt only once on action add failure + - Bluetooth: hci_event: Use HCI error defines instead of magic values + - Bluetooth: hci_conn: Only do ACL connections sequentially + - Bluetooth: Remove pending ACL connection attempts + - Bluetooth: hci_conn: Always use sk_timeo as conn_timeout + - Bluetooth: hci_conn: Fix UAF Write in __hci_acl_create_connection_sync + - Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue + - Bluetooth: hci_sync: Attempt to dequeue connection attempt + - Bluetooth: ISO: Reassemble PA data for bcast sink + - Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync + - Bluetooth: btusb: Fix triggering coredump implementation for QCA + - Bluetooth: hci_event: Fix sending HCI_OP_READ_ENC_KEY_SIZE + - Bluetooth: MGMT: Fix failing to MGMT_OP_ADD_UUID/MGMT_OP_REMOVE_UUID + - Bluetooth: btusb: mediatek: Fix double free of skb in coredump + - Bluetooth: hci_sync: Using hci_cmd_sync_submit when removing Adv Monitor + - Bluetooth: qca: set power_ctrl_enabled on NULL returned by + gpiod_get_optional() + - ipvs: Fix checksumming on GSO of SCTP packets + - net: openvswitch: Fix Use-After-Free in ovs_ct_exit + - mlxsw: Use refcount_t for reference counting + - mlxsw: spectrum_acl_tcam: Fix race in region ID allocation + - mlxsw: spectrum_acl_tcam: Fix race during rehash delayed work + - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during activity update + - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during rehash + - mlxsw: spectrum_acl_tcam: Rate limit error message + - mlxsw: spectrum_acl_tcam: Fix memory leak during rehash + - mlxsw: spectrum_acl_tcam: Fix warning during rehash + - mlxsw: spectrum_acl_tcam: Fix incorrect list API usage + - mlxsw: spectrum_acl_tcam: Fix memory leak when canceling rehash work + - eth: bnxt: fix counting packets discarded due to OOM and netpoll + - ARM: dts: imx6ull-tarragon: fix USB over-current polarity + - netfilter: nf_tables: honor table dormant flag from netdev release event + path + - net: phy: dp83869: Fix MII mode failure + - net: ti: icssg-prueth: Fix signedness bug in prueth_init_rx_chns() + - i40e: Do not use WQ_MEM_RECLAIM flag for workqueue + - i40e: Report MFS in decimal base instead of hex + - iavf: Fix TC config comparison with existing adapter TC config + - ice: fix LAG and VF lock dependency in ice_reset_vf() + - net: ethernet: ti: am65-cpts: Fix PTPv1 message type on TX packets + - octeontx2-af: fix the double free in rvu_npc_freemem() + - dpll: check that pin is registered in __dpll_pin_unregister() + - dpll: fix dpll_pin_on_pin_register() for multiple parent pins + - tls: fix lockless read of strp->msg_ready in ->poll + - af_unix: Suppress false-positive lockdep splat for spin_lock() in + __unix_gc(). + - netfs: Fix the pre-flush when appending to a file in writethrough mode + - drm/amd/display: Check DP Alt mode DPCS state via DMUB + - Revert "drm/amd/display: fix USB-C flag update after enc10 feature init" + - xhci: move event processing for one interrupter to a separate function + - usb: xhci: correct return value in case of STS_HCE + - KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled + - KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET" + - drm: add drm_gem_object_is_shared_for_memory_stats() helper + - drm/amdgpu: add shared fdinfo stats + - drm/amdgpu: fix visible VRAM handling during faults + - Revert "UBUNTU: SAUCE: selftests/seccomp: fix check of fds being assigned" + - selftests/seccomp: user_notification_addfd check nextfd is available + - selftests/seccomp: Change the syscall used in KILL_THREAD test + - selftests/seccomp: Handle EINVAL on unshare(CLONE_NEWPID) + - x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range + - x86/cpu: Fix check for RDPKRU in __show_regs() + - rust: phy: implement `Send` for `Registration` + - rust: kernel: require `Send` for `Module` implementations + - rust: don't select CONSTRUCTORS + - [Config] updateconfigs to drop CONSTRUCTORS for rust + - rust: init: remove impl Zeroable for Infallible + - rust: make mutually exclusive with CFI_CLANG + - kbuild: rust: remove unneeded `@rustc_cfg` to avoid ICE + - kbuild: rust: force `alloc` extern to allow "empty" Rust files + - rust: remove `params` from `module` macro example + - Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old() + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0bda:0x4853 + - Bluetooth: qca: fix NULL-deref on non-serdev suspend + - Bluetooth: qca: fix NULL-deref on non-serdev setup + - mtd: rawnand: qcom: Fix broken OP_RESET_DEVICE command in + qcom_misc_cmd_type_exec() + - mm/hugetlb: fix missing hugetlb_lock for resv uncharge + - mmc: sdhci-msm: pervent access to suspended controller + - mmc: sdhci-of-dwcmshc: th1520: Increase tuning loop count to 128 + - mm: create FOLIO_FLAG_FALSE and FOLIO_TYPE_OPS macros + - mm: support page_mapcount() on page_has_type() pages + - mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio() + - smb: client: Fix struct_group() usage in __packed structs + - smb3: missing lock when picking channel + - smb3: fix lock ordering potential deadlock in cifs_sync_mid_result + - btrfs: fallback if compressed IO fails for ENOSPC + - btrfs: fix wrong block_start calculation for btrfs_drop_extent_map_range() + - btrfs: scrub: run relocation repair when/only needed + - btrfs: fix information leak in btrfs_ioctl_logical_to_ino() + - x86/tdx: Preserve shared bit on mprotect() + - cpu: Re-enable CPU mitigations by default for !X86 architectures + - [Config] updateconfigs for CPU_MITIGATIONS + - eeprom: at24: fix memory corruption race condition + - LoongArch: Fix callchain parse error with kernel tracepoint events + - LoongArch: Fix access error when read fault on a write-only VMA + - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP + - arm64: dts: qcom: sm8450: Fix the msi-map entries + - arm64: dts: rockchip: enable internal pull-up for Q7_THRM# on RK3399 Puma + - dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state" + - dmaengine: xilinx: xdma: Fix wrong offsets in the buffers addresses in dma + descriptor + - dmaengine: xilinx: xdma: Fix synchronization issue + - drm/amdgpu/sdma5.2: use legacy HDP flush for SDMA2/3 + - drm/amdgpu: Assign correct bits for SDMA HDP flush + - drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call + - drm/amdgpu/pm: Remove gpu_od if it's an empty directory + - drm/amdgpu/umsch: don't execute umsch test when GPU is in reset/suspend + - drm/amdgpu: Fix leak when GPU memory allocation fails + - drm/amdkfd: Fix rescheduling of restore worker + - drm/amdkfd: Fix eviction fence handling + - irqchip/gic-v3-its: Prevent double free on error + - ACPI: CPPC: Use access_width over bit_width for system memory accesses + - ACPI: CPPC: Fix bit_offset shift in MASK_VAL() macro + - ACPI: CPPC: Fix access width used for PCC registers + - net/mlx5e: Advertise mlx5 ethernet driver updates sk_buff md_dst for MACsec + - ethernet: Add helper for assigning packet type when dest address does not + match device address + - net: b44: set pause params only when interface is up + - macsec: Enable devices to advertise whether they update sk_buff md_dst + during offloads + - macsec: Detect if Rx skb is macsec-related for offloading devices that + update md_dst + - stackdepot: respect __GFP_NOLOCKDEP allocation flag + - fbdev: fix incorrect address computation in deferred IO + - udp: preserve the connected status if only UDP cmsg + - mtd: limit OTP NVMEM cell parse to non-NAND devices + - mtd: diskonchip: work around ubsan link failure + - firmware: qcom: uefisecapp: Fix memory related IO errors and crashes + - phy: qcom: qmp-combo: Fix register base for QSERDES_DP_PHY_MODE + - phy: qcom: qmp-combo: Fix VCO div offset on v3 + - mm: turn folio_test_hugetlb into a PageType + - mm: zswap: fix shrinker NULL crash with cgroup_disable=memory + - dmaengine: owl: fix register access functions + - dmaengine: tegra186: Fix residual calculation + - idma64: Don't try to serve interrupts when device is powered off + - soundwire: amd: fix for wake interrupt handling for clockstop mode + - phy: marvell: a3700-comphy: Fix hardcoded array size + - phy: freescale: imx8m-pcie: fix pcie link-up instability + - phy: rockchip-snps-pcie3: fix bifurcation on rk3588 + - phy: rockchip-snps-pcie3: fix clearing PHP_GRF_PCIESEL_CON bits + - phy: rockchip: naneng-combphy: Fix mux on rk3588 + - phy: qcom: m31: match requested regulator name with dt schema + - dmaengine: idxd: Convert spinlock to mutex to lock evl workqueue + - dmaengine: idxd: Fix oops during rmmod on single-CPU platforms + - riscv: Fix TASK_SIZE on 64-bit NOMMU + - riscv: Fix loading 64-bit NOMMU kernels past the start of RAM + - phy: ti: tusb1210: Resolve charger-det crash if charger psy is unregistered + - dt-bindings: eeprom: at24: Fix ST M24C64-D compatible schema + - sched/eevdf: Always update V if se->on_rq when reweighting + - sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr + - riscv: hwprobe: fix invalid sign extension for RISCV_HWPROBE_EXT_ZVFHMIN + - RISC-V: selftests: cbo: Ensure asm operands match constraints, take 2 + - phy: qcom: qmp-combo: fix VCO div offset on v5_5nm and v6 + - bounds: Use the right number of bits for power-of-two CONFIG_NR_CPUS + - Bluetooth: hci_sync: Fix UAF in hci_acl_create_conn_sync + - Bluetooth: hci_sync: Fix UAF on create_le_conn_complete + - Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync + - Linux 6.8.9 + + * amdgpu hangs on DCN 3.5 at bootup: RIP: + 0010:dcn35_clk_mgr_construct+0x183/0x2210 [amdgpu] (LP: #2066233) + - drm/amd/display: Atom Integrated System Info v2_2 for DCN35 + + * [MTL] ACPI: PM: s2idle: Backport Linux ACPI s2idle patches to fix + suspend/resume issue (LP: #2069231) + - ACPI: PM: s2idle: Enable Low-Power S0 Idle MSFT UUID for non-AMD systems + - ACPI: PM: s2idle: Evaluate all Low-Power S0 Idle _DSM functions + + * Removing legacy virtio-pci devices causes kernel panic (LP: #2067862) + - virtio-pci: Check if is_avq is NULL + + * Mute/mic LEDs no function on ProBook 445/465 G11 (LP: #2069664) + - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 445/465 G11. + + * Mute/mic LEDs no function on ProBook 440/460 G11 (LP: #2067669) + - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 440/460 G11. + + * rtw89_8852ce - Lost WIFI connection after suspend (LP: #2065128) + - wifi: rtw89: reset AFEDIG register in power off sequence + - wifi: rtw89: 8852c: refine power sequence to imporve power consumption + + * CVE-2024-25742 + - x86/sev: Harden #VC instruction emulation somewhat + - x86/sev: Check for MWAITX and MONITORX opcodes in the #VC handler + + * Noble update: v6.8.9 upstream stable release (LP: #2070337) // + CVE-2024-35984 + - i2c: smbus: fix NULL function pointer dereference + + * Noble update: v6.8.9 upstream stable release (LP: #2070337) // + CVE-2024-35990 + - dma: xilinx_dpdma: Fix locking + + * Noble update: v6.8.9 upstream stable release (LP: #2070337) // + CVE-2024-35997 + - HID: i2c-hid: remove I2C_HID_READ_PENDING flag to prevent lock-up + + * CVE-2024-36016 + - tty: n_gsm: fix possible out-of-bounds in gsm0_receive() + + * CVE-2024-36008 + - ipv4: check for NULL idev in ip_route_use_hint() + + * CVE-2024-35992 + - phy: marvell: a3700-comphy: Fix out of bounds read + + -- Stefan Bader Fri, 05 Jul 2024 10:31:38 +0200 + +linux (6.8.0-38.38) noble; urgency=medium + + * noble/linux: 6.8.0-38.38 -proposed tracker (LP: #2068318) + + * race_sched in ubuntu_stress_smoke_test will cause kernel panic on 6.8 with + Azure Standard_A2_v2 instance (LP: #2068024) + - sched/eevdf: Prevent vlag from going out of bounds in reweight_eevdf() + + * Noble: btrfs: re-introduce 'norecovery' mount option (LP: #2068591) + - btrfs: re-introduce 'norecovery' mount option + + * Fix system hang while entering suspend with AMD Navi3x graphics + (LP: #2063417) + - drm/amdgpu/mes: fix use-after-free issue + + * Noble update: v6.8.8 upstream stable release (LP: #2068087) + - io_uring: Fix io_cqring_wait() not restoring sigmask on get_timespec64() + failure + - drm/i915/cdclk: Fix voltage_level programming edge case + - Revert "vmgenid: emit uevent when VMGENID updates" + - SUNRPC: Fix rpcgss_context trace event acceptor field + - selftests/ftrace: Limit length in subsystem-enable tests + - random: handle creditable entropy from atomic process context + - scsi: core: Fix handling of SCMD_FAIL_IF_RECOVERING + - net: usb: ax88179_178a: avoid writing the mac address before first reading + - btrfs: do not wait for short bulk allocation + - btrfs: zoned: do not flag ZEROOUT on non-dirty extent buffer + - r8169: fix LED-related deadlock on module removal + - r8169: add missing conditional compiling for call to r8169_remove_leds + - scsi: ufs: qcom: Add missing interconnect bandwidth values for Gear 5 + - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get() + - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get() + - netfilter: br_netfilter: skip conntrack input hook for promisc packets + - netfilter: nft_set_pipapo: constify lookup fn args where possible + - netfilter: nft_set_pipapo: walk over current view on netlink dump + - netfilter: flowtable: validate pppoe header + - netfilter: flowtable: incorrect pppoe tuple + - af_unix: Call manage_oob() for every skb in unix_stream_read_generic(). + - af_unix: Don't peek OOB data without MSG_OOB. + - net: sparx5: flower: fix fragment flags handling + - net/mlx5: Lag, restore buckets number to default after hash LAG deactivation + - net/mlx5: Restore mistakenly dropped parts in register devlink flow + - net/mlx5e: Prevent deadlock while disabling aRFS + - net: change maximum number of UDP segments to 128 + - octeontx2-pf: fix FLOW_DIS_IS_FRAGMENT implementation + - selftests/tcp_ao: Make RST tests less flaky + - selftests/tcp_ao: Zero-init tcp_ao_info_opt + - selftests/tcp_ao: Fix fscanf() call for format-security + - selftests/tcp_ao: Printing fixes to confirm with format-security + - net: stmmac: Apply half-duplex-less constraint for DW QoS Eth only + - net: stmmac: Fix max-speed being ignored on queue re-init + - net: stmmac: Fix IP-cores specific MAC capabilities + - ice: tc: check src_vsi in case of traffic from VF + - ice: tc: allow zero flags in parsing tc flower + - ice: Fix checking for unsupported keys on non-tunnel device + - tun: limit printing rate when illegal packet received by tun dev + - net: dsa: mt7530: fix mirroring frames received on local port + - net: dsa: mt7530: fix port mirroring for MT7988 SoC switch + - s390/ism: Properly fix receive message buffer allocation + - netfilter: nf_tables: missing iterator type in lookup walk + - netfilter: nf_tables: restore set elements when delete set fails + - gpiolib: swnode: Remove wrong header inclusion + - netfilter: nf_tables: fix memleak in map from abort path + - net/sched: Fix mirred deadlock on device recursion + - net: ethernet: mtk_eth_soc: fix WED + wifi reset + - ravb: Group descriptor types used in Rx ring + - net: ravb: Count packets instead of descriptors in R-Car RX path + - net: ravb: Allow RX loop to move past DMA mapping errors + - net: ethernet: ti: am65-cpsw-nuss: cleanup DMA Channels before using them + - NFSD: fix endianness issue in nfsd4_encode_fattr4 + - RDMA/rxe: Fix the problem "mutex_destroy missing" + - RDMA/cm: Print the old state when cm_destroy_id gets timeout + - RDMA/mlx5: Fix port number for counter query in multi-port configuration + - perf annotate: Make sure to call symbol__annotate2() in TUI + - perf lock contention: Add a missing NULL check + - s390/qdio: handle deferred cc1 + - s390/cio: fix race condition during online processing + - iommufd: Add missing IOMMUFD_DRIVER kconfig for the selftest + - iommufd: Add config needed for iommufd_fail_nth + - drm: nv04: Fix out of bounds access + - drm/v3d: Don't increment `enabled_ns` twice + - userfaultfd: change src_folio after ensuring it's unpinned in UFFDIO_MOVE + - thunderbolt: Introduce tb_port_reset() + - thunderbolt: Introduce tb_path_deactivate_hop() + - thunderbolt: Make tb_switch_reset() support Thunderbolt 2, 3 and USB4 + routers + - thunderbolt: Reset topology created by the boot firmware + - drm/panel: visionox-rm69299: don't unregister DSI device + - drm/radeon: make -fstrict-flex-arrays=3 happy + - ALSA: hda/realtek: Fix volumn control of ThinkBook 16P Gen4 + - thermal/debugfs: Add missing count increment to thermal_debug_tz_trip_up() + - platform/x86/amd/pmc: Extend Framework 13 quirk to more BIOSes + - interconnect: qcom: x1e80100: Remove inexistent ACV_PERF BCM + - interconnect: Don't access req_list while it's being manipulated + - clk: Remove prepare_lock hold assertion in __clk_release() + - clk: Initialize struct clk_core kref earlier + - clk: Get runtime PM before walking tree during disable_unused + - clk: Get runtime PM before walking tree for clk_summary + - clk: mediatek: Do a runtime PM get on controllers during probe + - clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port + - selftests/powerpc/papr-vpd: Fix missing variable initialization + - x86/bugs: Fix BHI retpoline check + - x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ + - block: propagate partition scanning errors to the BLKRRPART ioctl + - net/mlx5: E-switch, store eswitch pointer before registering devlink_param + - ALSA: seq: ump: Fix conversion from MIDI2 to MIDI1 UMP messages + - ALSA: hda/tas2781: correct the register for pow calibrated data + - ALSA: hda/realtek: Add quirks for Huawei Matebook D14 NBLB-WAX9N + - ALSA: hda/realtek - Enable audio jacks of Haier Boyue G42 with ALC269VC + - usb: misc: onboard_usb_hub: Disable the USB hub clock on failure + - misc: rtsx: Fix rts5264 driver status incorrect when card removed + - thunderbolt: Avoid notify PM core about runtime PM resume + - thunderbolt: Fix wake configurations after device unplug + - thunderbolt: Do not create DisplayPort tunnels on adapters of the same + router + - comedi: vmk80xx: fix incomplete endpoint checking + - serial: mxs-auart: add spinlock around changing cts state + - serial/pmac_zilog: Remove flawed mitigation for rx irq flood + - serial: 8250_dw: Revert: Do not reclock if already at correct rate + - serial: stm32: Return IRQ_NONE in the ISR if no handling happend + - serial: stm32: Reset .throttled state in .startup() + - serial: core: Fix regression when runtime PM is not enabled + - serial: core: Clearing the circular buffer before NULLifying it + - serial: core: Fix missing shutdown and startup for serial base port + - USB: serial: option: add Fibocom FM135-GL variants + - USB: serial: option: add support for Fibocom FM650/FG650 + - USB: serial: option: add Lonsung U8300/U9300 product + - USB: serial: option: support Quectel EM060K sub-models + - USB: serial: option: add Rolling RW101-GL and RW135-GL support + - USB: serial: option: add Telit FN920C04 rmnet compositions + - Revert "usb: cdc-wdm: close race between read and workqueue" + - usb: dwc2: host: Fix dereference issue in DDMA completion flow. + - usb: Disable USB3 LPM at shutdown + - usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport + error + - usb: typec: tcpm: Correct the PDO counting in pd_set + - mei: me: disable RPL-S on SPS and IGN firmwares + - speakup: Avoid crash on very long word + - fs: sysfs: Fix reference leak in sysfs_break_active_protection() + - sched: Add missing memory barrier in switch_mm_cid + - KVM: x86: Snapshot if a vCPU's vendor model is AMD vs. Intel compatible + - KVM: x86/pmu: Disable support for adaptive PEBS + - KVM: x86/pmu: Do not mask LVTPC when handling a PMI on AMD platforms + - KVM: x86/mmu: x86: Don't overflow lpage_info when checking attributes + - KVM: x86/mmu: Write-protect L2 SPTEs in TDP MMU when clearing dirty status + - arm64/head: Disable MMU at EL2 before clearing HCR_EL2.E2H + - arm64: hibernate: Fix level3 translation fault in swsusp_save() + - init/main.c: Fix potential static_command_line memory overflow + - mm/madvise: make MADV_POPULATE_(READ|WRITE) handle VM_FAULT_RETRY properly + - mm/userfaultfd: allow hugetlb change protection upon poison entry + - mm,swapops: update check in is_pfn_swap_entry for hwpoison entries + - mm/memory-failure: fix deadlock when hugetlb_optimize_vmemmap is enabled + - mm/shmem: inline shmem_is_huge() for disabled transparent hugepages + - fuse: fix leaked ENOSYS error on first statx call + - drm/amdkfd: Fix memory leak in create_process failure + - drm/amdgpu: remove invalid resource->start check v2 + - drm/ttm: stop pooling cached NUMA pages v2 + - drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init + - drm/vmwgfx: Fix prime import/export + - drm/vmwgfx: Sort primary plane formats by order of preference + - drm/vmwgfx: Fix crtc's atomic check conditional + - nouveau: fix instmem race condition around ptr stores + - bootconfig: use memblock_free_late to free xbc memory to buddy + - Squashfs: check the inode number is not the invalid value of zero + - nilfs2: fix OOB in nilfs_set_de_type + - fork: defer linking file vma until vma is fully initialized + - net: dsa: mt7530: fix improper frames on all 25MHz and 40MHz XTAL MT7530 + - net: dsa: mt7530: fix enabling EEE on MT7531 switch on all boards + - ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf + - ksmbd: validate request buffer size in smb2_allocate_rsp_buf() + - ksmbd: clear RENAME_NOREPLACE before calling vfs_rename + - ksmbd: common: use struct_group_attr instead of struct_group for + network_open_info + - thunderbolt: Reset only non-USB4 host routers in resume + - Linux 6.8.8 + + * Fix inaudible HDMI/DP audio on USB-C MST dock (LP: #2064689) + - drm/i915/audio: Fix audio time stamp programming for DP + + * Add Cirrus Logic CS35L56 amplifier support (LP: #2062135) + - ALSA: hda: realtek: Re-work CS35L41 fixups to re-use for other amps + - ALSA: hda/realtek: Add quirks for HP G11 Laptops using CS35L56 + + * net:fib_rule_tests.sh in ubuntu_kselftests_net fails on Noble (LP: #2066332) + - Revert "UBUNTU: SAUCE: selftests: net: fix "from" match test in + fib_rule_tests.sh" + + * mtk_t7xx WWAN module fails to probe with: Invalid device status 0x1 + (LP: #2049358) + - Revert "UBUNTU: SAUCE: net: wwan: t7xx: PCIe reset rescan" + - Revert "UBUNTU: SAUCE: net: wwan: t7xx: Add AP CLDMA" + - net: wwan: t7xx: Add AP CLDMA + - wwan: core: Add WWAN fastboot port type + - net: wwan: t7xx: Add sysfs attribute for device state machine + - net: wwan: t7xx: Infrastructure for early port configuration + - net: wwan: t7xx: Add fastboot WWAN port + + * Pull-request to address TPM bypass issue (LP: #2037688) + - [Config]: Configure TPM drivers as builtins for arm64 in annotations + + * re-enable Ubuntu FAN in the Noble kernel (LP: #2064508) + - SAUCE: fan: add VXLAN implementation + - SAUCE: fan: Fix NULL pointer dereference + - SAUCE: fan: support vxlan strict length validation + + * update for V3 kernel bits and improved multiple fan slice support + (LP: #1470091) // re-enable Ubuntu FAN in the Noble kernel (LP: #2064508) + - SAUCE: fan: tunnel multiple mapping mode (v3) + + * TCP memory leak, slow network (arm64) (LP: #2045560) + - net: make SK_MEMORY_PCPU_RESERV tunable + - net: fix sk_memory_allocated_{add|sub} vs softirqs + + * panel flickering after the i915.psr2 is enabled (LP: #2046315) + - drm/i915/alpm: Add ALPM register definitions + - drm/i915/psr: Add alpm_parameters struct + - drm/i915/alpm: Calculate ALPM Entry check + - drm/i915/alpm: Alpm aux wake configuration for lnl + - drm/i915/display: Make intel_dp_aux_fw_sync_len available for PSR code + - drm/i915/psr: Improve fast and IO wake lines calculation + - drm/i915/psr: Calculate IO wake and fast wake lines for DISPLAY_VER < 12 + - drm/i915/display: Increase number of fast wake precharge pulses + + * I2C HID device sometimes fails to initialize causing touchpad to not work + (LP: #2061040) + - HID: i2c-hid: Revert to await reset ACK before reading report descriptor + + * Fix the RTL8852CE BT FW Crash based on SER false alarm (LP: #2060904) + - wifi: rtw89: disable txptctrl IMR to avoid flase alarm + - wifi: rtw89: pci: correct TX resource checking for PCI DMA channel of + firmware command + + * [X13s] Fingerprint reader is not working (LP: #2065376) + - SAUCE: arm64: dts: qcom: sc8280xp: Add USB DWC3 Multiport controller + - SAUCE: arm64: dts: qcom: sc8280xp-x13s: enable USB MP and fingerprint reader + + * Fix random HuC/GuC initialization failure of Intel i915 driver + (LP: #2061049) + - drm/i915/huc: Allow for very slow HuC loading + + * Add support of TAS2781 amp of audio (LP: #2064064) + - ALSA: hda/tas2781: Add new vendor_id and subsystem_id to support ThinkPad + ICE-1 + + * Noble update: v6.8.7 upstream stable release (LP: #2065912) + - smb3: fix Open files on server counter going negative + - ata: libata-core: Allow command duration limits detection for ACS-4 drives + - ata: libata-scsi: Fix ata_scsi_dev_rescan() error path + - drm/amdgpu/vpe: power on vpe when hw_init + - batman-adv: Avoid infinite loop trying to resize local TT + - ceph: redirty page before returning AOP_WRITEPAGE_ACTIVATE + - ceph: switch to use cap_delay_lock for the unlink delay list + - virtio_net: Do not send RSS key if it is not supported + - arm64: tlb: Fix TLBI RANGE operand + - ARM: dts: imx7s-warp: Pass OV2680 link-frequencies + - raid1: fix use-after-free for original bio in raid1_write_request() + - ring-buffer: Only update pages_touched when a new page is touched + - Bluetooth: Fix memory leak in hci_req_sync_complete() + - drm/amd/pm: fixes a random hang in S4 for SMU v13.0.4/11 + - platform/chrome: cros_ec_uart: properly fix race condition + - ACPI: scan: Do not increase dep_unmet for already met dependencies + - PM: s2idle: Make sure CPUs will wakeup directly on resume + - media: cec: core: remove length check of Timer Status + - btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() + - ARM: OMAP2+: fix bogus MMC GPIO labels on Nokia N8x0 + - ARM: OMAP2+: fix N810 MMC gpiod table + - mmc: omap: fix broken slot switch lookup + - mmc: omap: fix deferred probe + - mmc: omap: restore original power up/down steps + - ARM: OMAP2+: fix USB regression on Nokia N8x0 + - firmware: arm_ffa: Fix the partition ID check in ffa_notification_info_get() + - firmware: arm_scmi: Make raw debugfs entries non-seekable + - cxl/mem: Fix for the index of Clear Event Record Handle + - cxl/core/regs: Fix usage of map->reg_type in cxl_decode_regblock() before + assigned + - arm64: dts: freescale: imx8mp-venice-gw72xx-2x: fix USB vbus regulator + - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix USB vbus regulator + - drm/msm: Add newlines to some debug prints + - drm/msm/dpu: don't allow overriding data from catalog + - drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more + sensible + - dt-bindings: display/msm: sm8150-mdss: add DP node + - arm64: dts: imx8-ss-conn: fix usdhc wrong lpcg clock order + - cxl/core: Fix initialization of mbox_cmd.size_out in get event + - Revert "drm/qxl: simplify qxl_fence_wait" + - nouveau: fix function cast warning + - drm/msm/adreno: Set highest_bank_bit for A619 + - scsi: hisi_sas: Modify the deadline for ata_wait_after_reset() + - scsi: qla2xxx: Fix off by one in qla_edif_app_getstats() + - net: openvswitch: fix unwanted error log on timeout policy probing + - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file + - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING + - octeontx2-pf: Fix transmit scheduler resource leak + - block: fix q->blkg_list corruption during disk rebind + - lib: checksum: hide unused expected_csum_ipv6_magic[] + - geneve: fix header validation in geneve[6]_xmit_skb + - s390/ism: fix receive message buffer allocation + - bnxt_en: Fix possible memory leak in bnxt_rdma_aux_device_init() + - bnxt_en: Fix error recovery for RoCE ulp client + - bnxt_en: Reset PTP tx_avail after possible firmware reset + - ACPI: bus: allow _UID matching for integer zero + - base/node / ACPI: Enumerate node access class for 'struct access_coordinate' + - ACPI: HMAT: Introduce 2 levels of generic port access class + - ACPI: HMAT / cxl: Add retrieval of generic port coordinates for both access + classes + - cxl: Split out combine_coordinates() for common shared usage + - cxl: Split out host bridge access coordinates + - cxl: Remove checking of iter in cxl_endpoint_get_perf_coordinates() + - cxl: Fix retrieving of access_coordinates in PCIe path + - net: ks8851: Inline ks8851_rx_skb() + - net: ks8851: Handle softirqs at the end of IRQ thread to fix hang + - af_unix: Clear stale u->oob_skb. + - octeontx2-af: Fix NIX SQ mode and BP config + - ipv6: fib: hide unused 'pn' variable + - ipv4/route: avoid unused-but-set-variable warning + - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr + - pds_core: use pci_reset_function for health reset + - pds_core: Fix pdsc_check_pci_health function to use work thread + - Bluetooth: ISO: Align broadcast sync_timeout with connection timeout + - Bluetooth: ISO: Don't reject BT_ISO_QOS if parameters are unset + - Bluetooth: hci_sync: Use QoS to determine which PHY to scan + - Bluetooth: hci_sync: Fix using the same interval and window for Coded PHY + - Bluetooth: SCO: Fix not validating setsockopt user input + - Bluetooth: RFCOMM: Fix not validating setsockopt user input + - Bluetooth: L2CAP: Fix not validating setsockopt user input + - Bluetooth: ISO: Fix not validating setsockopt user input + - Bluetooth: hci_sock: Fix not validating setsockopt user input + - Bluetooth: l2cap: Don't double set the HCI_CONN_MGMT_CONNECTED bit + - netfilter: complete validation of user input + - net/mlx5: SF, Stop waiting for FW as teardown was called + - net/mlx5: Register devlink first under devlink lock + - net/mlx5: offset comp irq index in name by one + - net/mlx5: Properly link new fs rules into the tree + - net/mlx5: Correctly compare pkt reformat ids + - net/mlx5e: RSS, Block changing channels number when RXFH is configured + - net/mlx5e: Fix mlx5e_priv_init() cleanup flow + - net/mlx5e: HTB, Fix inconsistencies with QoS SQs number + - net/mlx5e: Do not produce metadata freelist entries in Tx port ts WQE xmit + - net: sparx5: fix wrong config being used when reconfiguring PCS + - Revert "s390/ism: fix receive message buffer allocation" + - net: dsa: mt7530: trap link-local frames regardless of ST Port State + - af_unix: Do not use atomic ops for unix_sk(sk)->inflight. + - af_unix: Fix garbage collector racing against connect() + - net: ena: Fix potential sign extension issue + - net: ena: Wrong missing IO completions check order + - net: ena: Fix incorrect descriptor free behavior + - net: ena: Set tx_info->xdpf value to NULL + - drm/xe/display: Fix double mutex initialization + - drm/xe/hwmon: Cast result to output precision on left shift of operand + - tracing: hide unused ftrace_event_id_fops + - iommu/vt-d: Fix wrong use of pasid config + - iommu/vt-d: Allocate local memory for page request queue + - iommu/vt-d: Fix WARN_ON in iommu probe path + - io_uring: refactor DEFER_TASKRUN multishot checks + - io_uring: disable io-wq execution of multishot NOWAIT requests + - btrfs: qgroup: correctly model root qgroup rsv in convert + - btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations + - btrfs: record delayed inode root in transaction + - btrfs: qgroup: convert PREALLOC to PERTRANS after record_root_in_trans + - io_uring/net: restore msg_control on sendzc retry + - kprobes: Fix possible use-after-free issue on kprobe registration + - fs/proc: remove redundant comments from /proc/bootconfig + - fs/proc: Skip bootloader comment if no embedded kernel parameters + - scsi: sg: Avoid sg device teardown race + - scsi: sg: Avoid race in error handling & drop bogus warn + - accel/ivpu: Check return code of ipc->lock init + - accel/ivpu: Fix PCI D0 state entry in resume + - accel/ivpu: Put NPU back to D3hot after failed resume + - accel/ivpu: Return max freq for DRM_IVPU_PARAM_CORE_CLOCK_RATE + - accel/ivpu: Fix deadlock in context_xa + - drm/vmwgfx: Enable DMA mappings with SEV + - drm/i915/vrr: Disable VRR when using bigjoiner + - drm/amdkfd: Reset GPU on queue preemption failure + - drm/ast: Fix soft lockup + - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + - drm/client: Fully protect modes[] with dev->mode_config.mutex + - drm/msm/dp: fix runtime PM leak on disconnect + - drm/msm/dp: fix runtime PM leak on connect failure + - drm/amdgpu/umsch: reinitialize write pointer in hw init + - arm64: dts: imx8qm-ss-dma: fix can lpcg indices + - arm64: dts: imx8-ss-dma: fix can lpcg indices + - arm64: dts: imx8-ss-dma: fix adc lpcg indices + - arm64: dts: imx8-ss-conn: fix usb lpcg indices + - arm64: dts: imx8-ss-dma: fix pwm lpcg indices + - arm64: dts: imx8-ss-lsio: fix pwm lpcg indices + - arm64: dts: imx8-ss-dma: fix spi lpcg indices + - vhost: Add smp_rmb() in vhost_vq_avail_empty() + - vhost: Add smp_rmb() in vhost_enable_notify() + - perf/x86: Fix out of range data + - x86/cpu: Actually turn off mitigations by default for + SPECULATION_MITIGATIONS=n + - selftests/timers/posix_timers: Reimplement check_timer_distribution() + - selftests: timers: Fix posix_timers ksft_print_msg() warning + - selftests: timers: Fix abs() warning in posix_timers test + - selftests: kselftest: Mark functions that unconditionally call exit() as + __noreturn + - x86/apic: Force native_apic_mem_read() to use the MOV instruction + - irqflags: Explicitly ignore lockdep_hrtimer_exit() argument + - selftests: kselftest: Fix build failure with NOLIBC + - kernfs: annotate different lockdep class for of->mutex of writable files + - x86/bugs: Fix return type of spectre_bhi_state() + - x86/bugs: Fix BHI documentation + - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES + - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr' + - x86/bugs: Fix BHI handling of RRSBA + - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation + - x86/bugs: Remove CONFIG_BHI_MITIGATION_AUTO and spectre_bhi=auto + - [Config] updateconfigs to remove obsolete SPECTRE_BHI_AUTO + - x86/bugs: Replace CONFIG_SPECTRE_BHI_{ON,OFF} with + CONFIG_MITIGATION_SPECTRE_BHI + - [Config] updateconfigs to enable new MITIGATION_SPECTRE_BHI + - drm/i915/cdclk: Fix CDCLK programming order when pipes are active + - drm/i915/psr: Disable PSR when bigjoiner is used + - drm/i915: Disable port sync when bigjoiner is used + - drm/i915: Disable live M/N updates when using bigjoiner + - drm/amdgpu: Reset dGPU if suspend got aborted + - drm/amdgpu: always force full reset for SOC21 + - drm/amdgpu: fix incorrect number of active RBs for gfx11 + - drm/amdgpu: differentiate external rev id for gfx 11.5.0 + - drm/amd/display: Program VSC SDP colorimetry for all DP sinks >= 1.4 + - drm/amd/display: Set VSC SDP Colorimetry same way for MST and SST + - drm/amd/display: Do not recursively call manual trigger programming + - drm/amd/display: Return max resolution supported by DWB + - drm/amd/display: always reset ODM mode in context when adding first plane + - drm/amd/display: fix disable otg wa logic in DCN316 + - Linux 6.8.7 + + * Noble update: v6.8.6 upstream stable release (LP: #2065899) + - amdkfd: use calloc instead of kzalloc to avoid integer overflow + - wifi: ath9k: fix LNA selection in ath_ant_try_scan() + - wifi: rtw89: fix null pointer access when abort scan + - bnx2x: Fix firmware version string character counts + - net: stmmac: dwmac-starfive: Add support for JH7100 SoC + - net: phy: phy_device: Prevent nullptr exceptions on ISR + - wifi: rtw89: pci: validate RX tag for RXQ and RPQ + - wifi: rtw89: pci: enlarge RX DMA buffer to consider size of RX descriptor + - VMCI: Fix memcpy() run-time warning in dg_dispatch_as_host() + - wifi: iwlwifi: pcie: Add the PCI device id for new hardware + - arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs + - net: dsa: qca8k: put MDIO controller OF node if unavailable + - arm64: dts: qcom: qrb2210-rb1: disable cluster power domains + - printk: For @suppress_panic_printk check for other CPU in panic + - panic: Flush kernel log buffer at the end + - dump_stack: Do not get cpu_sync for panic CPU + - wifi: iwlwifi: pcie: Add new PCI device id and CNVI + - cpuidle: Avoid potential overflow in integer multiplication + - ARM: dts: rockchip: fix rk3288 hdmi ports node + - ARM: dts: rockchip: fix rk322x hdmi ports node + - arm64: dts: rockchip: fix rk3328 hdmi ports node + - arm64: dts: rockchip: fix rk3399 hdmi ports node + - net: add netdev_lockdep_set_classes() to virtual drivers + - arm64: dts: qcom: qcs6490-rb3gen2: Declare GCC clocks protected + - pmdomain: ti: Add a null pointer check to the omap_prm_domain_init + - pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain + - ACPI: resource: Add IRQ override quirk for ASUS ExpertBook B2502FBA + - ionic: set adminq irq affinity + - net: skbuff: add overflow debug check to pull/push helpers + - firmware: tegra: bpmp: Return directly after a failed kzalloc() in + get_filename() + - wifi: brcmfmac: Add DMI nvram filename quirk for ACEPC W5 Pro + - wifi: mt76: mt7915: add locking for accessing mapped registers + - wifi: mt76: mt7996: disable AMSDU for non-data frames + - wifi: mt76: mt7996: add locking for accessing mapped registers + - ACPI: x86: Move acpi_quirk_skip_serdev_enumeration() out of + CONFIG_X86_ANDROID_TABLETS + - ACPI: x86: Add DELL0501 handling to acpi_quirk_skip_serdev_enumeration() + - pstore/zone: Add a null pointer check to the psz_kmsg_read + - tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num() + - net: pcs: xpcs: Return EINVAL in the internal methods + - dma-direct: Leak pages on dma_set_decrypted() failure + - wifi: ath11k: decrease MHI channel buffer length to 8KB + - iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev + - cpufreq: Don't unregister cpufreq cooling on CPU hotplug + - overflow: Allow non-type arg to type_max() and type_min() + - wifi: iwlwifi: Add missing MODULE_FIRMWARE() for *.pnvm + - wifi: cfg80211: check A-MSDU format more carefully + - btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks() + - btrfs: export: handle invalid inode or root reference in btrfs_get_parent() + - btrfs: send: handle path ref underflow in header iterate_inode_ref() + - ice: use relative VSI index for VFs instead of PF VSI number + - net/smc: reduce rtnl pressure in smc_pnet_create_pnetids_list() + - netdev: let netlink core handle -EMSGSIZE errors + - Bluetooth: btintel: Fix null ptr deref in btintel_read_version + - Bluetooth: btmtk: Add MODULE_FIRMWARE() for MT7922 + - Bluetooth: Add new quirk for broken read key length on ATS2851 + - drm/vc4: don't check if plane->state->fb == state->fb + - drm/ci: uprev mesa version: fix kdl commit fetch + - drm/amdgpu: Skip do PCI error slot reset during RAS recovery + - Input: synaptics-rmi4 - fail probing if memory allocation for "phys" fails + - drm: panel-orientation-quirks: Add quirk for GPD Win Mini + - ASoC: SOF: amd: Optimize quirk for Valve Galileo + - drm/ttm: return ENOSPC from ttm_bo_mem_space v3 + - scsi: ufs: qcom: Avoid re-init quirk when gears match + - drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz + - pinctrl: renesas: checker: Limit cfg reg enum checks to provided IDs + - sysv: don't call sb_bread() with pointers_lock held + - scsi: lpfc: Fix possible memory leak in lpfc_rcv_padisc() + - drm/amd/display: Disable idle reallow as part of command/gpint execution + - isofs: handle CDs with bad root inode but good Joliet root directory + - ASoC: Intel: sof_rt5682: dmi quirk cleanup for mtl boards + - ASoC: Intel: common: DMI remap for rebranded Intel NUC M15 (LAPRC710) + laptops + - rcu/nocb: Fix WARN_ON_ONCE() in the rcu_nocb_bypass_lock() + - rcu-tasks: Repair RCU Tasks Trace quiescence check + - Julia Lawall reported this null pointer dereference, this should fix it. + - media: sta2x11: fix irq handler cast + - ALSA: firewire-lib: handle quirk to calculate payload quadlets as data block + counter + - drm/panel: simple: Add BOE BP082WX1-100 8.2" panel + - x86/vdso: Fix rethunk patching for vdso-image-{32,64}.o + - ASoC: Intel: avs: Populate board selection with new I2S entries + - ext4: add a hint for block bitmap corrupt state in mb_groups + - ext4: forbid commit inconsistent quota data when errors=remount-ro + - drm/amd/display: Fix nanosec stat overflow + - accel/habanalabs: increase HL_MAX_STR to 64 bytes to avoid warnings + - i2c: designware: Fix RX FIFO depth define on Wangxun 10Gb NIC + - HID: input: avoid polling stylus battery on Chromebook Pompom + - drm/amd/amdgpu: Fix potential ioremap() memory leaks in amdgpu_device_init() + - drm: Check output polling initialized before disabling + - drm: Check polling initialized before enabling in + drm_helper_probe_single_connector_modes + - SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned + int + - PCI: Disable D3cold on Asus B1400 PCI-NVMe bridge + - Revert "ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default" + - libperf evlist: Avoid out-of-bounds access + - crypto: iaa - Fix async_disable descriptor leak + - input/touchscreen: imagis: Correct the maximum touch area value + - drivers/perf: hisi: Enable HiSilicon Erratum 162700402 quirk for HIP09 + - block: prevent division by zero in blk_rq_stat_sum() + - RDMA/cm: add timeout to cm_destroy_id wait + - Input: imagis - use FIELD_GET where applicable + - Input: allocate keycode for Display refresh rate toggle + - platform/x86: acer-wmi: Add support for Acer PH16-71 + - platform/x86: acer-wmi: Add predator_v4 module parameter + - platform/x86: touchscreen_dmi: Add an extra entry for a variant of the Chuwi + Vi8 tablet + - perf/x86/amd/lbr: Discard erroneous branch entries + - ALSA: hda/realtek: Add quirk for Lenovo Yoga 9 14IMH9 + - ktest: force $buildonly = 1 for 'make_warnings_file' test type + - Input: xpad - add support for Snakebyte GAMEPADs + - ring-buffer: use READ_ONCE() to read cpu_buffer->commit_page in concurrent + environment + - tools: iio: replace seekdir() in iio_generic_buffer + - bus: mhi: host: Add MHI_PM_SYS_ERR_FAIL state + - kernfs: RCU protect kernfs_nodes and avoid kernfs_idr_lock in + kernfs_find_and_get_node_by_id() + - usb: typec: ucsi: Add qcm6490-pmic-glink as needing PDOS quirk + - thunderbolt: Calculate DisplayPort tunnel bandwidth after DPRX capabilities + read + - usb: gadget: uvc: refactor the check for a valid buffer in the pump worker + - usb: gadget: uvc: mark incomplete frames with UVC_STREAM_ERR + - usb: typec: ucsi: Limit read size on v1.2 + - serial: 8250_of: Drop quirk fot NPCM from 8250_port + - thunderbolt: Keep the domain powered when USB4 port is in redrive mode + - usb: typec: tcpci: add generic tcpci fallback compatible + - usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined + - ASoC: amd: yc: Fix non-functional mic on ASUS M7600RE + - thermal/of: Assume polling-delay(-passive) 0 when absent + - ASoC: soc-core.c: Skip dummy codec when adding platforms + - x86/xen: attempt to inflate the memory balloon on PVH + - fbdev: viafb: fix typo in hw_bitblt_1 and hw_bitblt_2 + - io_uring: clear opcode specific data for an early failure + - modpost: fix null pointer dereference + - drivers/nvme: Add quirks for device 126f:2262 + - fbmon: prevent division by zero in fb_videomode_from_videomode() + - ALSA: hda/realtek: Add quirks for some Clevo laptops + - drm/amdgpu: Init zone device and drm client after mode-1 reset on reload + - gcc-plugins/stackleak: Avoid .head.text section + - media: mediatek: vcodec: Fix oops when HEVC init fails + - media: mediatek: vcodec: adding lock to protect decoder context list + - media: mediatek: vcodec: adding lock to protect encoder context list + - randomize_kstack: Improve entropy diffusion + - platform/x86/intel/hid: Don't wake on 5-button releases + - platform/x86: intel-vbtn: Update tablet mode switch at end of probe + - nouveau: fix devinit paths to only handle display on GSP. + - Bluetooth: btintel: Fixe build regression + - net: mpls: error out if inner headers are not set + - VMCI: Fix possible memcpy() run-time warning in + vmci_datagram_invoke_guest_handler() + - x86/vdso: Fix rethunk patching for vdso-image-x32.o too + - Revert "drm/amd/amdgpu: Fix potential ioremap() memory leaks in + amdgpu_device_init()" + - Linux 6.8.6 + + * Noble update: v6.8.5 upstream stable release (LP: #2065400) + - scripts/bpf_doc: Use silent mode when exec make cmd + - xsk: Don't assume metadata is always requested in TX completion + - s390/bpf: Fix bpf_plt pointer arithmetic + - bpf, arm64: fix bug in BPF_LDX_MEMSX + - dma-buf: Fix NULL pointer dereference in sanitycheck() + - arm64: bpf: fix 32bit unconditional bswap + - nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet + - nfsd: Fix error cleanup path in nfsd_rename() + - tools: ynl: fix setting presence bits in simple nests + - mlxbf_gige: stop PHY during open() error paths + - wifi: iwlwifi: mvm: pick the version of SESSION_PROTECTION_NOTIF + - wifi: iwlwifi: mvm: rfi: fix potential response leaks + - wifi: iwlwifi: mvm: include link ID when releasing frames + - ALSA: hda: cs35l56: Set the init_done flag before component_add() + - ice: Refactor FW data type and fix bitmap casting issue + - ice: fix memory corruption bug with suspend and rebuild + - ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa() + - igc: Remove stale comment about Tx timestamping + - drm/xe: Remove unused xe_bo->props struct + - drm/xe: Add exec_queue.sched_props.job_timeout_ms + - drm/xe/guc_submit: use jiffies for job timeout + - drm/xe/queue: fix engine_class bounds check + - drm/xe/device: fix XE_MAX_GT_PER_TILE check + - drm/xe/device: fix XE_MAX_TILES_PER_DEVICE check + - dpll: indent DPLL option type by a tab + - s390/qeth: handle deferred cc1 + - net: hsr: hsr_slave: Fix the promiscuous mode in offload mode + - tcp: properly terminate timers for kernel sockets + - net: wwan: t7xx: Split 64bit accesses to fix alignment issues + - drm/rockchip: vop2: Remove AR30 and AB30 format support + - selftests: vxlan_mdb: Fix failures with old libnet + - gpiolib: Fix debug messaging in gpiod_find_and_request() + - ACPICA: debugger: check status of acpi_evaluate_object() in + acpi_db_walk_for_fields() + - net: hns3: fix index limit to support all queue stats + - net: hns3: fix kernel crash when devlink reload during pf initialization + - net: hns3: mark unexcuted loopback test result as UNEXECUTED + - tls: recv: process_rx_list shouldn't use an offset with kvec + - tls: adjust recv return with async crypto and failed copy to userspace + - tls: get psock ref after taking rxlock to avoid leak + - mlxbf_gige: call request_irq() after NAPI initialized + - drm/amd/display: Update P010 scaling cap + - drm/amd/display: Send DTBCLK disable message on first commit + - bpf: Protect against int overflow for stack access size + - cifs: Fix duplicate fscache cookie warnings + - netfilter: nf_tables: reject destroy command to remove basechain hooks + - netfilter: nf_tables: reject table flag and netdev basechain updates + - netfilter: nf_tables: skip netdev hook unregistration if table is dormant + - iommu: Validate the PASID in iommu_attach_device_pasid() + - net: bcmasp: Bring up unimac after PHY link up + - net: lan743x: Add set RFE read fifo threshold for PCI1x1x chips + - Octeontx2-af: fix pause frame configuration in GMP mode + - inet: inet_defrag: prevent sk release while still in use + - drm/i915: Stop doing double audio enable/disable on SDVO and g4x+ DP + - drm/i915/display: Disable AuxCCS framebuffers if built for Xe + - drm/i915/xelpg: Extend some workarounds/tuning to gfx version 12.74 + - drm/i915/mtl: Update workaround 14018575942 + - drm/i915: Do not print 'pxp init failed with 0' when it succeed + - dm integrity: fix out-of-range warning + - modpost: do not make find_tosym() return NULL + - kbuild: make -Woverride-init warnings more consistent + - mm/treewide: replace pud_large() with pud_leaf() + - Revert "x86/mm/ident_map: Use gbpages only where full GB page should be + mapped." + - gpio: cdev: sanitize the label before requesting the interrupt + - RISC-V: KVM: Fix APLIC setipnum_le/be write emulation + - RISC-V: KVM: Fix APLIC in_clrip[x] read emulation + - KVM: arm64: Fix host-programmed guest events in nVHE + - KVM: arm64: Fix out-of-IPA space translation fault handling + - selinux: avoid dereference of garbage after mount failure + - r8169: fix issue caused by buggy BIOS on certain boards with RTL8168d + - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word + - x86/bpf: Fix IP after emitting call depth accounting + - Revert "Bluetooth: hci_qca: Set BDA quirk bit if fwnode exists in DT" + - arm64: dts: qcom: sc7180-trogdor: mark bluetooth address as broken + - Bluetooth: qca: fix device-address endianness + - Bluetooth: add quirk for broken address properties + - Bluetooth: hci_event: set the conn encrypted before conn establishes + - Bluetooth: Fix TOCTOU in HCI debugfs implementation + - netfilter: nf_tables: release batch on table validation from abort path + - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path + - selftests: mptcp: join: fix dev in check_endpoint + - net/rds: fix possible cp null dereference + - net: usb: ax88179_178a: avoid the interface always configured as random + address + - net: mana: Fix Rx DMA datasize and skb_over_panic + - vsock/virtio: fix packet delivery to tap device + - netfilter: nf_tables: reject new basechain after table flag update + - netfilter: nf_tables: flush pending destroy work before exit_net release + - netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get() + - netfilter: nf_tables: discard table flag update with pending basechain + deletion + - netfilter: validate user input for expected length + - vboxsf: Avoid an spurious warning if load_nls_xxx() fails + - bpf, sockmap: Prevent lock inversion deadlock in map delete elem + - mptcp: prevent BPF accessing lowat from a subflow socket. + - x86/retpoline: Do the necessary fixup to the Zen3/4 srso return thunk for + !SRSO + - KVM: arm64: Use TLBI_TTL_UNKNOWN in __kvm_tlb_flush_vmid_range() + - KVM: arm64: Ensure target address is granule-aligned for range TLBI + - net/sched: act_skbmod: prevent kernel-infoleak + - net: dsa: sja1105: Fix parameters order in sja1110_pcs_mdio_write_c45() + - net/sched: fix lockdep splat in qdisc_tree_reduce_backlog() + - net: stmmac: fix rx queue priority assignment + - net: phy: micrel: lan8814: Fix when enabling/disabling 1-step timestamping + - net: txgbe: fix i2c dev name cannot match clkdev + - net: fec: Set mac_managed_pm during probe + - net: phy: micrel: Fix potential null pointer dereference + - net: dsa: mv88e6xxx: fix usable ports on 88e6020 + - selftests: net: gro fwd: update vxlan GRO test expectations + - gro: fix ownership transfer + - idpf: fix kernel panic on unknown packet types + - ice: fix enabling RX VLAN filtering + - i40e: Fix VF MAC filter removal + - tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non- + wildcard addresses. + - erspan: make sure erspan_base_hdr is present in skb->head + - selftests: reuseaddr_conflict: add missing new line at the end of the output + - tcp: Fix bind() regression for v6-only wildcard and v4(-mapped-v6) non- + wildcard addresses. + - ax25: fix use-after-free bugs caused by ax25_ds_del_timer + - e1000e: Workaround for sporadic MDI error on Meteor Lake systems + - ipv6: Fix infinite recursion in fib6_dump_done(). + - mlxbf_gige: stop interface during shutdown + - r8169: skip DASH fw status checks when DASH is disabled + - udp: do not accept non-tunnel GSO skbs landing in a tunnel + - udp: do not transition UDP GRO fraglist partial checksums to unnecessary + - udp: prevent local UDP tunnel packets from being GROed + - octeontx2-af: Fix issue with loading coalesced KPU profiles + - octeontx2-pf: check negative error code in otx2_open() + - octeontx2-af: Add array index check + - i40e: fix i40e_count_filters() to count only active/new filters + - i40e: fix vf may be used uninitialized in this function warning + - i40e: Enforce software interrupt during busy-poll exit + - drm/amd: Flush GFXOFF requests in prepare stage + - e1000e: Minor flow correction in e1000_shutdown function + - e1000e: move force SMBUS from enable ulp function to avoid PHY loss issue + - mean_and_variance: Drop always failing tests + - net: ravb: Let IP-specific receive function to interrogate descriptors + - net: ravb: Always process TX descriptor ring + - net: ravb: Always update error counters + - KVM: SVM: Use unsigned integers when dealing with ASIDs + - KVM: SVM: Add support for allowing zero SEV ASIDs + - selftests: mptcp: connect: fix shellcheck warnings + - selftests: mptcp: use += operator to append strings + - mptcp: don't account accept() of non-MPC client as fallback to TCP + - 9p: Fix read/write debug statements to report server reply + - ASoC: wm_adsp: Fix missing mutex_lock in wm_adsp_write_ctl() + - ASoC: cs42l43: Correct extraction of data pointer in suspend/resume + - riscv: mm: Fix prototype to avoid discarding const + - riscv: hwprobe: do not produce frtace relocation + - drivers/perf: riscv: Disable PERF_SAMPLE_BRANCH_* while not supported + - block: count BLK_OPEN_RESTRICT_WRITES openers + - RISC-V: Update AT_VECTOR_SIZE_ARCH for new AT_MINSIGSTKSZ + - ASoC: amd: acp: fix for acp pdm configuration check + - regmap: maple: Fix cache corruption in regcache_maple_drop() + - ALSA: hda: cs35l56: Add ACPI device match tables + - drm/panfrost: fix power transition timeout warnings + - nouveau/uvmm: fix addr/range calcs for remap operations + - drm/prime: Unbreak virtgpu dma-buf export + - ASoC: rt5682-sdw: fix locking sequence + - ASoC: rt711-sdca: fix locking sequence + - ASoC: rt711-sdw: fix locking sequence + - ASoC: rt712-sdca-sdw: fix locking sequence + - ASoC: rt722-sdca-sdw: fix locking sequence + - ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw + - spi: s3c64xx: Extract FIFO depth calculation to a dedicated macro + - spi: s3c64xx: sort headers alphabetically + - spi: s3c64xx: explicitly include + - spi: s3c64xx: remove else after return + - spi: s3c64xx: define a magic value + - spi: s3c64xx: allow full FIFO masks + - spi: s3c64xx: determine the fifo depth only once + - spi: s3c64xx: Use DMA mode from fifo size + - ASoC: amd: acp: fix for acp_init function error handling + - regmap: maple: Fix uninitialized symbol 'ret' warnings + - ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit + - scsi: mylex: Fix sysfs buffer lengths + - scsi: sd: Unregister device if device_add_disk() failed in sd_probe() + - Revert "ALSA: emu10k1: fix synthesizer sample playback position and caching" + - drm/i915/dp: Fix DSC state HW readout for SST connectors + - cifs: Fix caching to try to do open O_WRONLY as rdwr on server + - spi: mchp-pci1xxx: Fix a possible null pointer dereference in + pci1xxx_spi_probe + - s390/pai: fix sampling event removal for PMU device driver + - thermal: gov_power_allocator: Allow binding without cooling devices + - thermal: gov_power_allocator: Allow binding without trip points + - drm/i915/gt: Limit the reserved VM space to only the platforms that need it + - ata: sata_mv: Fix PCI device ID table declaration compilation warning + - ASoC: SOF: amd: fix for false dsp interrupts + - SUNRPC: Fix a slow server-side memory leak with RPC-over-TCP + - riscv: use KERN_INFO in do_trap + - riscv: Fix warning by declaring arch_cpu_idle() as noinstr + - riscv: Disable preemption when using patch_map() + - nfsd: hold a lighter-weight client reference over CB_RECALL_ANY + - lib/stackdepot: move stack_record struct definition into the header + - stackdepot: rename pool_index to pool_index_plus_1 + - x86/retpoline: Add NOENDBR annotation to the SRSO dummy return thunk + - Revert "drm/amd/display: Send DTBCLK disable message on first commit" + - gpio: cdev: check for NULL labels when sanitizing them for irqs + - gpio: cdev: fix missed label sanitizing in debounce_setup() + - ksmbd: don't send oplock break if rename fails + - ksmbd: validate payload size in ipc response + - ksmbd: do not set SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1 + - ALSA: hda: Add pplcllpl/u members to hdac_ext_stream + - ALSA: hda/realtek - Fix inactive headset mic jack + - ALSA: hda/realtek: Add sound quirks for Lenovo Legion slim 7 16ARHA7 models + - ALSA: hda/realtek: cs35l41: Support ASUS ROG G634JYR + - ALSA: hda/realtek: Update Panasonic CF-SZ6 quirk to support headset with + microphone + - io_uring/kbuf: get rid of lower BGID lists + - io_uring/kbuf: get rid of bl->is_ready + - io_uring/kbuf: protect io_buffer_list teardown with a reference + - io_uring/rw: don't allow multishot reads without NOWAIT support + - io_uring: use private workqueue for exit work + - io_uring/kbuf: hold io_buffer_list reference over mmap + - ASoC: SOF: Add dsp_max_burst_size_in_ms member to snd_sof_pcm_stream + - ASoC: SOF: ipc4-topology: Save the DMA maximum burst size for PCMs + - ASoC: SOF: Intel: hda-pcm: Use dsp_max_burst_size_in_ms to place constraint + - ASoC: SOF: Intel: hda: Implement get_stream_position (Linear Link Position) + - ASoC: SOF: Intel: mtl/lnl: Use the generic get_stream_position callback + - ASoC: SOF: Introduce a new callback pair to be used for PCM delay reporting + - ASoC: SOF: Intel: Set the dai/host get frame/byte counter callbacks + - ASoC: SOF: Intel: hda-common-ops: Do not set the get_stream_position + callback + - ASoC: SOF: ipc4-pcm: Use the snd_sof_pcm_get_dai_frame_counter() for + pcm_delay + - ASoC: SOF: Remove the get_stream_position callback + - ASoC: SOF: ipc4-pcm: Move struct sof_ipc4_timestamp_info definition locally + - ASoC: SOF: ipc4-pcm: Combine the SOF_IPC4_PIPE_PAUSED cases in pcm_trigger + - ASoC: SOF: ipc4-pcm: Invalidate the stream_start_offset in PAUSED state + - ASoC: SOF: sof-pcm: Add pointer callback to sof_ipc_pcm_ops + - ASoC: SOF: ipc4-pcm: Correct the delay calculation + - ASoC: SOF: Intel: hda: Compensate LLP in case it is not reset + - driver core: Introduce device_link_wait_removal() + - of: dynamic: Synchronize of_changeset_destroy() with the devlink removals + - of: module: prevent NULL pointer dereference in vsnprintf() + - x86/mm/pat: fix VM_PAT handling in COW mappings + - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank() + - x86/coco: Require seeding RNG with RDRAND on CoCo systems + - perf/x86/intel/ds: Don't clear ->pebs_data_cfg for the last PEBS event + - riscv: Fix vector state restore in rt_sigreturn() + - arm64/ptrace: Use saved floating point state type to determine SVE layout + - mm/secretmem: fix GUP-fast succeeding on secretmem folios + - selftests/mm: include strings.h for ffsl + - s390/entry: align system call table on 8 bytes + - riscv: Fix spurious errors from __get/put_kernel_nofault + - riscv: process: Fix kernel gp leakage + - smb: client: fix UAF in smb2_reconnect_server() + - smb: client: guarantee refcounted children from parent session + - smb: client: refresh referral without acquiring refpath_lock + - smb: client: handle DFS tcons in cifs_construct_tcon() + - smb: client: serialise cifs_construct_tcon() with cifs_mount_mutex + - smb3: retrying on failed server close + - smb: client: fix potential UAF in cifs_debug_files_proc_show() + - smb: client: fix potential UAF in cifs_stats_proc_write() + - smb: client: fix potential UAF in cifs_stats_proc_show() + - smb: client: fix potential UAF in cifs_dump_full_key() + - smb: client: fix potential UAF in smb2_is_valid_oplock_break() + - smb: client: fix potential UAF in smb2_is_valid_lease_break() + - smb: client: fix potential UAF in is_valid_oplock_break() + - smb: client: fix potential UAF in smb2_is_network_name_deleted() + - smb: client: fix potential UAF in cifs_signal_cifsd_for_reconnect() + - drm/i915/mst: Limit MST+DSC to TGL+ + - drm/i915/mst: Reject FEC+MST on ICL + - drm/i915/dp: Fix the computation for compressed_bpp for DISPLAY < 13 + - drm/i915/gt: Disable HW load balancing for CCS + - drm/i915/gt: Do not generate the command streamer for all the CCS + - drm/i915/gt: Enable only one CCS for compute workload + - drm/xe: Use ring ops TLB invalidation for rebinds + - drm/xe: Rework rebinding + - Revert "x86/mpparse: Register APIC address only once" + - bpf: put uprobe link's path and task in release callback + - bpf: support deferring bpf_link dealloc to after RCU grace period + - efi/libstub: Add generic support for parsing mem_encrypt= + - x86/boot: Move mem_encrypt= parsing to the decompressor + - x86/sme: Move early SME kernel encryption handling into .head.text + - x86/sev: Move early startup code into .head.text section + - Linux 6.8.5 + + * CVE-2024-26926 + - binder: check offset alignment in binder_get_object() + + * CVE-2024-26922 + - drm/amdgpu: validate the parameters of bo mapping operations more clearly + + * CVE-2024-26924 + - netfilter: nft_set_pipapo: do not free live element + + -- Stefan Bader Fri, 07 Jun 2024 14:51:17 +0200 + +linux (6.8.0-35.35) noble; urgency=medium + + * noble/linux: 6.8.0-35.35 -proposed tracker (LP: #2065886) + + * CVE-2024-21823 + - VFIO: Add the SPR_DSA and SPR_IAX devices to the denylist + - dmaengine: idxd: add a new security check to deal with a hardware erratum + - dmaengine: idxd: add a write() method for applications to submit work + + -- Roxana Nicolescu Mon, 20 May 2024 16:26:15 +0200 + +linux (6.8.0-34.34) noble; urgency=medium + + * noble/linux: 6.8.0-34.34 -proposed tracker (LP: #2065167) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/2024.04.29) + + -- Roxana Nicolescu Wed, 08 May 2024 13:14:41 +0200 + +linux (6.8.0-32.32) noble; urgency=medium + + * noble/linux: 6.8.0-32.32 -proposed tracker (LP: #2064344) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + - [Packaging] update variants + - [Packaging] update annotations scripts + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/2024.04.29) + + * Enable Nezha board (LP: #1975592) + - [Config] Enable CONFIG_REGULATOR_FIXED_VOLTAGE on riscv64 + + * Enable Nezha board (LP: #1975592) // Enable StarFive VisionFive 2 board + (LP: #2013232) + - [Config] Enable CONFIG_SERIAL_8250_DW on riscv64 + + * RISC-V kernel config is out of sync with other archs (LP: #1981437) + - [Config] Sync riscv64 config with other architectures + + * obsolete out-of-tree ivsc dkms in favor of in-tree one (LP: #2061747) + - ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device + - Revert "mei: vsc: Call wake_up() in the threaded IRQ handler" + - mei: vsc: Unregister interrupt handler for system suspend + - media: ipu-bridge: Add ov01a10 in Dell XPS 9315 + - SAUCE: media: ipu-bridge: Support more sensors + + * Fix after-suspend-mediacard/sdhc-insert test failed (LP: #2042500) + - PCI/ASPM: Move pci_configure_ltr() to aspm.c + - PCI/ASPM: Always build aspm.c + - PCI/ASPM: Move pci_save_ltr_state() to aspm.c + - PCI/ASPM: Save L1 PM Substates Capability for suspend/resume + - PCI/ASPM: Call pci_save_ltr_state() from pci_save_pcie_state() + - PCI/ASPM: Disable L1 before configuring L1 Substates + - PCI/ASPM: Update save_state when configuration changes + + * RTL8852BE fw security fail then lost WIFI function during suspend/resume + cycle (LP: #2063096) + - wifi: rtw89: download firmware with five times retry + + * intel_rapl_common: Add support for ARL and LNL (LP: #2061953) + - powercap: intel_rapl: Add support for Lunar Lake-M paltform + - powercap: intel_rapl: Add support for Arrow Lake + + * Kernel panic during checkbox stress_ng_test on Grace running noble 6.8 + (arm64+largemem) kernel (LP: #2058557) + - aio: Fix null ptr deref in aio_complete() wakeup + + * Avoid creating non-working backlight sysfs knob from ASUS board + (LP: #2060422) + - platform/x86: asus-wmi: Consider device is absent when the read is ~0 + + * Include cifs.ko in linux-modules package (LP: #2042546) + - [Packaging] Replace fs/cifs with fs/smb/client in inclusion list + + * Add Real-time Linux Analysis tool (rtla) to linux-tools (LP: #2059080) + - SAUCE: rtla: fix deb build + - [Packaging] add Real-time Linux Analysis tool (rtla) to linux-tools + - [Packaging] update dependencies for rtla + + * Noble update: v6.8.4 upstream stable release (LP: #2060533) + - Revert "workqueue: Shorten events_freezable_power_efficient name" + - Revert "workqueue: Don't call cpumask_test_cpu() with -1 CPU in + wq_update_node_max_active()" + - Revert "workqueue: Implement system-wide nr_active enforcement for unbound + workqueues" + - Revert "workqueue: Introduce struct wq_node_nr_active" + - Revert "workqueue: RCU protect wq->dfl_pwq and implement accessors for it" + - Revert "workqueue: Make wq_adjust_max_active() round-robin pwqs while + activating" + - Revert "workqueue: Move nr_active handling into helpers" + - Revert "workqueue: Replace pwq_activate_inactive_work() with + [__]pwq_activate_work()" + - Revert "workqueue: Factor out pwq_is_empty()" + - Revert "workqueue: Move pwq->max_active to wq->max_active" + - Revert "workqueue.c: Increase workqueue name length" + - Linux 6.8.4 + + * Noble update: v6.8.3 upstream stable release (LP: #2060531) + - drm/vmwgfx: Unmap the surface before resetting it on a plane state + - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach + - wifi: brcmfmac: avoid invalid list operation when vendor attach fails + - media: staging: ipu3-imgu: Set fields before media_entity_pads_init() + - arm64: dts: qcom: sc7280: Add additional MSI interrupts + - remoteproc: virtio: Fix wdg cannot recovery remote processor + - clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd + - smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr() + - smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity() + - arm: dts: marvell: Fix maxium->maxim typo in brownstone dts + - drm/vmwgfx: Fix possible null pointer derefence with invalid contexts + - arm64: dts: qcom: sm8450-hdk: correct AMIC4 and AMIC5 microphones + - serial: max310x: fix NULL pointer dereference in I2C instantiation + - drm/vmwgfx: Fix the lifetime of the bo cursor memory + - pci_iounmap(): Fix MMIO mapping leak + - media: xc4000: Fix atomicity violation in xc4000_get_frequency + - media: mc: Add local pad to pipeline regardless of the link state + - media: mc: Fix flags handling when creating pad links + - media: nxp: imx8-isi: Check whether crossbar pad is non-NULL before access + - media: mc: Add num_links flag to media_pad + - media: mc: Rename pad variable to clarify intent + - media: mc: Expand MUST_CONNECT flag to always require an enabled link + - media: nxp: imx8-isi: Mark all crossbar sink pads as MUST_CONNECT + - md: use RCU lock to protect traversal in md_spares_need_change() + - KVM: Always flush async #PF workqueue when vCPU is being destroyed + - arm64: dts: qcom: sm8550-qrd: correct WCD9385 TX port mapping + - arm64: dts: qcom: sm8550-mtp: correct WCD9385 TX port mapping + - cpufreq: amd-pstate: Fix min_perf assignment in amd_pstate_adjust_perf() + - thermal/intel: Fix intel_tcc_get_temp() to support negative CPU temperature + - powercap: intel_rapl: Fix a NULL pointer dereference + - powercap: intel_rapl: Fix locking in TPMI RAPL + - powercap: intel_rapl_tpmi: Fix a register bug + - powercap: intel_rapl_tpmi: Fix System Domain probing + - powerpc/smp: Adjust nr_cpu_ids to cover all threads of a core + - powerpc/smp: Increase nr_cpu_ids to include the boot CPU + - sparc64: NMI watchdog: fix return value of __setup handler + - sparc: vDSO: fix return value of __setup handler + - selftests/mqueue: Set timeout to 180 seconds + - pinctrl: qcom: sm8650-lpass-lpi: correct Kconfig name + - ext4: correct best extent lstart adjustment logic + - drm/amdgpu/display: Address kdoc for 'is_psr_su' in 'fill_dc_dirty_rects' + - block: Clear zone limits for a non-zoned stacked queue + - kasan/test: avoid gcc warning for intentional overflow + - bounds: support non-power-of-two CONFIG_NR_CPUS + - fat: fix uninitialized field in nostale filehandles + - fuse: fix VM_MAYSHARE and direct_io_allow_mmap + - mfd: twl: Select MFD_CORE + - ubifs: Set page uptodate in the correct place + - ubi: Check for too small LEB size in VTBL code + - ubi: correct the calculation of fastmap size + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - mtd: rawnand: meson: fix scrambling mode value in command macro + - md/md-bitmap: fix incorrect usage for sb_index + - x86/nmi: Fix the inverse "in NMI handler" check + - parisc/unaligned: Rewrite 64-bit inline assembly of emulate_ldd() + - parisc: Avoid clobbering the C/B bits in the PSW with tophys and tovirt + macros + - parisc: Fix ip_fast_csum + - parisc: Fix csum_ipv6_magic on 32-bit systems + - parisc: Fix csum_ipv6_magic on 64-bit systems + - parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit builds + - md/raid5: fix atomicity violation in raid5_cache_count + - iio: adc: rockchip_saradc: fix bitmask for channels on SARADCv2 + - iio: adc: rockchip_saradc: use mask for write_enable bitfield + - docs: Restore "smart quotes" for quotes + - cpufreq: Limit resolving a frequency to policy min/max + - PM: suspend: Set mem_sleep_current during kernel command line setup + - vfio/pds: Always clear the save/restore FDs on reset + - clk: qcom: gcc-ipq5018: fix terminating of frequency table arrays + - clk: qcom: gcc-ipq6018: fix terminating of frequency table arrays + - clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays + - clk: qcom: gcc-ipq9574: fix terminating of frequency table arrays + - clk: qcom: camcc-sc8280xp: fix terminating of frequency table arrays + - clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays + - clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays + - usb: xhci: Add error handling in xhci_map_urb_for_dma + - powerpc/fsl: Fix mfpmr build errors with newer binutils + - USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB + - USB: serial: add device ID for VeriFone adapter + - USB: serial: cp210x: add ID for MGP Instruments PDS100 + - wifi: mac80211: track capability/opmode NSS separately + - USB: serial: option: add MeiG Smart SLM320 product + - KVM: x86/xen: inject vCPU upcall vector when local APIC is enabled + - USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M + - PM: sleep: wakeirq: fix wake irq warning in system suspend + - mmc: tmio: avoid concurrent runs of mmc_request_done() + - fuse: replace remaining make_bad_inode() with fuse_make_bad() + - fuse: fix root lookup with nonzero generation + - fuse: don't unhash root + - usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros + - usb: dwc3-am62: fix module unload/reload behavior + - usb: dwc3-am62: Disable wakeup at remove + - serial: core: only stop transmit when HW fifo is empty + - serial: Lock console when calling into driver before registration + - btrfs: qgroup: always free reserved space for extent records + - btrfs: fix off-by-one chunk length calculation at contains_pending_extent() + - wifi: rtw88: Add missing VID/PIDs for 8811CU and 8821CU + - docs: Makefile: Add dependency to $(YNL_INDEX) for targets other than + htmldocs + - PCI/PM: Drain runtime-idle callbacks before driver removal + - PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports + - Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"" + - md: don't clear MD_RECOVERY_FROZEN for new dm-raid until resume + - md: export helpers to stop sync_thread + - md: export helper md_is_rdwr() + - md: add a new helper reshape_interrupted() + - dm-raid: really frozen sync_thread during suspend + - md/dm-raid: don't call md_reap_sync_thread() directly + - dm-raid: add a new helper prepare_suspend() in md_personality + - dm-raid456, md/raid456: fix a deadlock for dm-raid456 while io concurrent + with reshape + - dm-raid: fix lockdep waring in "pers->hot_add_disk" + - powerpc: xor_vmx: Add '-mhard-float' to CFLAGS + - mac802154: fix llsec key resources release in mac802154_llsec_key_del + - mm: swap: fix race between free_swap_and_cache() and swapoff() + - mmc: core: Fix switch on gp3 partition + - Bluetooth: btnxpuart: Fix btnxpuart_close + - leds: trigger: netdev: Fix kernel panic on interface rename trig notify + - drm/etnaviv: Restore some id values + - landlock: Warn once if a Landlock action is requested while disabled + - io_uring: fix mshot read defer taskrun cqe posting + - hwmon: (amc6821) add of_match table + - io_uring: fix io_queue_proc modifying req->flags + - ext4: fix corruption during on-line resize + - nvmem: meson-efuse: fix function pointer type mismatch + - slimbus: core: Remove usage of the deprecated ida_simple_xx() API + - phy: tegra: xusb: Add API to retrieve the port number of phy + - usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic + - speakup: Fix 8bit characters from direct synth + - debugfs: fix wait/cancellation handling during remove + - PCI/AER: Block runtime suspend when handling errors + - io_uring/net: correctly handle multishot recvmsg retry setup + - io_uring: fix mshot io-wq checks + - PCI: qcom: Disable ASPM L0s for sc8280xp, sa8540p and sa8295p + - sparc32: Fix parport build with sparc32 + - nfs: fix UAF in direct writes + - NFS: Read unlock folio on nfs_page_create_from_folio() error + - kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1 + - PCI: qcom: Enable BDF to SID translation properly + - PCI: dwc: endpoint: Fix advertised resizable BAR size + - PCI: hv: Fix ring buffer size calculation + - cifs: prevent updating file size from server if we have a read/write lease + - cifs: allow changing password during remount + - thermal/drivers/mediatek: Fix control buffer enablement on MT7896 + - vfio/pci: Disable auto-enable of exclusive INTx IRQ + - vfio/pci: Lock external INTx masking ops + - vfio/platform: Disable virqfds on cleanup + - vfio/platform: Create persistent IRQ handlers + - vfio/fsl-mc: Block calling interrupt handler without trigger + - tpm,tpm_tis: Avoid warning splat at shutdown + - ksmbd: replace generic_fillattr with vfs_getattr + - ksmbd: retrieve number of blocks using vfs_getattr in + set_file_allocation_info + - platform/x86/intel/tpmi: Change vsec offset to u64 + - io_uring/rw: return IOU_ISSUE_SKIP_COMPLETE for multishot retry + - io_uring: clean rings on NO_MMAP alloc fail + - ring-buffer: Do not set shortest_full when full target is hit + - ring-buffer: Fix full_waiters_pending in poll + - ring-buffer: Use wait_event_interruptible() in ring_buffer_wait() + - tracing/ring-buffer: Fix wait_on_pipe() race + - dlm: fix user space lkb refcounting + - soc: fsl: qbman: Always disable interrupts when taking cgr_lock + - soc: fsl: qbman: Use raw spinlock for cgr_lock + - s390/zcrypt: fix reference counting on zcrypt card objects + - drm/probe-helper: warn about negative .get_modes() + - drm/panel: do not return negative error codes from drm_panel_get_modes() + - drm/exynos: do not return negative values from .get_modes() + - drm/imx/ipuv3: do not return negative values from .get_modes() + - drm/vc4: hdmi: do not return negative values from .get_modes() + - clocksource/drivers/timer-riscv: Clear timer interrupt on timer + initialization + - memtest: use {READ,WRITE}_ONCE in memory scanning + - Revert "block/mq-deadline: use correct way to throttling write requests" + - lsm: use 32-bit compatible data types in LSM syscalls + - lsm: handle the NULL buffer case in lsm_fill_user_ctx() + - f2fs: mark inode dirty for FI_ATOMIC_COMMITTED flag + - f2fs: truncate page cache before clearing flags when aborting atomic write + - nilfs2: fix failure to detect DAT corruption in btree and direct mappings + - nilfs2: prevent kernel bug at submit_bh_wbc() + - cifs: make sure server interfaces are requested only for SMB3+ + - cifs: reduce warning log level for server not advertising interfaces + - cifs: open_cached_dir(): add FILE_READ_EA to desired access + - mtd: rawnand: Fix and simplify again the continuous read derivations + - mtd: rawnand: Add a helper for calculating a page index + - mtd: rawnand: Ensure all continuous terms are always in sync + - mtd: rawnand: Constrain even more when continuous reads are enabled + - cpufreq: dt: always allocate zeroed cpumask + - io_uring/futex: always remove futex entry for cancel all + - io_uring/waitid: always remove waitid entry for cancel all + - x86/CPU/AMD: Update the Zenbleed microcode revisions + - ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16() + - net: esp: fix bad handling of pages from page_pool + - NFSD: Fix nfsd_clid_class use of __string_len() macro + - drm/i915: Add missing ; to __assign_str() macros in tracepoint code + - net: hns3: tracing: fix hclgevf trace event strings + - cxl/trace: Properly initialize cxl_poison region name + - ksmbd: fix potencial out-of-bounds when buffer offset is invalid + - virtio: reenable config if freezing device failed + - LoongArch: Change __my_cpu_offset definition to avoid mis-optimization + - LoongArch: Define the __io_aw() hook as mmiowb() + - LoongArch/crypto: Clean up useless assignment operations + - wireguard: netlink: check for dangling peer via is_dead instead of empty + list + - wireguard: netlink: access device through ctx instead of peer + - wireguard: selftests: set RISCV_ISA_FALLBACK on riscv{32,64} + - ahci: asm1064: asm1166: don't limit reported ports + - drm/amd/display: Change default size for dummy plane in DML2 + - drm/amdgpu: amdgpu_ttm_gart_bind set gtt bound flag + - drm/amdgpu/pm: Fix NULL pointer dereference when get power limit + - drm/amdgpu/pm: Check the validity of overdiver power limit + - drm/amd/display: Override min required DCFCLK in dml1_validate + - drm/amd/display: Allow dirty rects to be sent to dmub when abm is active + - drm/amd/display: Init DPPCLK from SMU on dcn32 + - drm/amd/display: Update odm when ODM combine is changed on an otg master + pipe with no plane + - drm/amd/display: Fix idle check for shared firmware state + - drm/amd/display: Amend coasting vtotal for replay low hz + - drm/amd/display: Lock all enabled otg pipes even with no planes + - drm/amd/display: Implement wait_for_odm_update_pending_complete + - drm/amd/display: Return the correct HDCP error code + - drm/amd/display: Add a dc_state NULL check in dc_state_release + - drm/amd/display: Fix noise issue on HDMI AV mute + - dm snapshot: fix lockup in dm_exception_table_exit + - x86/pm: Work around false positive kmemleak report in msr_build_context() + - wifi: brcmfmac: add per-vendor feature detection callback + - wifi: brcmfmac: cfg80211: Use WSEC to set SAE password + - wifi: brcmfmac: Demote vendor-specific attach/detach messages to info + - drm/ttm: Make sure the mapped tt pages are decrypted when needed + - drm/amd/display: Unify optimize_required flags and VRR adjustments + - drm/amd/display: Add more checks for exiting idle in DC + - btrfs: add set_folio_extent_mapped() helper + - btrfs: replace sb::s_blocksize by fs_info::sectorsize + - btrfs: add helpers to get inode from page/folio pointers + - btrfs: add helpers to get fs_info from page/folio pointers + - btrfs: add helper to get fs_info from struct inode pointer + - btrfs: qgroup: validate btrfs_qgroup_inherit parameter + - vfio: Introduce interface to flush virqfd inject workqueue + - vfio/pci: Create persistent INTx handler + - drm/bridge: add ->edid_read hook and drm_bridge_edid_read() + - drm/bridge: lt8912b: use drm_bridge_edid_read() + - drm/bridge: lt8912b: clear the EDID property on failures + - drm/bridge: lt8912b: do not return negative values from .get_modes() + - drm/amd/display: Remove pixle rate limit for subvp + - drm/amd/display: Revert Remove pixle rate limit for subvp + - workqueue: Shorten events_freezable_power_efficient name + - drm/amd/display: Use freesync when `DRM_EDID_FEATURE_CONTINUOUS_FREQ` found + - netfilter: nf_tables: reject constant set with timeout + - Revert "crypto: pkcs7 - remove sha1 support" + - x86/efistub: Call mixed mode boot services on the firmware's stack + - ASoC: amd: yc: Revert "Fix non-functional mic on Lenovo 21J2" + - ASoC: amd: yc: Revert "add new YC platform variant (0x63) support" + - Fix memory leak in posix_clock_open() + - wifi: rtw88: 8821cu: Fix connection failure + - x86/Kconfig: Remove CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT + - x86/sev: Fix position dependent variable references in startup code + - clocksource/drivers/arm_global_timer: Fix maximum prescaler value + - ARM: 9352/1: iwmmxt: Remove support for PJ4/PJ4B cores + - ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses + - entry: Respect changes to system call number by trace_sys_enter() + - swiotlb: Fix double-allocation of slots due to broken alignment handling + - swiotlb: Honour dma_alloc_coherent() alignment in swiotlb_alloc() + - swiotlb: Fix alignment checks when both allocation and DMA masks are present + - iommu/dma: Force swiotlb_max_mapping_size on an untrusted device + - printk: Update @console_may_schedule in console_trylock_spinning() + - irqchip/renesas-rzg2l: Flush posted write in irq_eoi() + - irqchip/renesas-rzg2l: Rename rzg2l_tint_eoi() + - irqchip/renesas-rzg2l: Rename rzg2l_irq_eoi() + - irqchip/renesas-rzg2l: Prevent spurious interrupts when setting trigger type + - kprobes/x86: Use copy_from_kernel_nofault() to read from unsafe address + - efi/libstub: fix efi_random_alloc() to allocate memory at alloc_min or + higher address + - x86/mpparse: Register APIC address only once + - x86/fpu: Keep xfd_state in sync with MSR_IA32_XFD + - efi: fix panic in kdump kernel + - pwm: img: fix pwm clock lookup + - selftests/mm: Fix build with _FORTIFY_SOURCE + - btrfs: handle errors returned from unpin_extent_cache() + - btrfs: fix warning messages not printing interval at unpin_extent_range() + - btrfs: do not skip re-registration for the mounted device + - mfd: intel-lpss: Switch to generalized quirk table + - mfd: intel-lpss: Introduce QUIRK_CLOCK_DIVIDER_UNITY for XPS 9530 + - drm/i915: Replace a memset() with zero initialization + - drm/i915: Try to preserve the current shared_dpll for fastset on type-c + ports + - drm/i915: Include the PLL name in the debug messages + - drm/i915: Suppress old PLL pipe_mask checks for MG/TC/TBT PLLs + - crypto: iaa - Fix nr_cpus < nr_iaa case + - drm/amd/display: Prevent crash when disable stream + - ALSA: hda/tas2781: remove digital gain kcontrol + - ALSA: hda/tas2781: add locks to kcontrols + - mm: zswap: fix writeback shinker GFP_NOIO/GFP_NOFS recursion + - init: open /initrd.image with O_LARGEFILE + - x86/efistub: Add missing boot_params for mixed mode compat entry + - efi/libstub: Cast away type warning in use of max() + - x86/efistub: Reinstate soft limit for initrd loading + - prctl: generalize PR_SET_MDWE support check to be per-arch + - ARM: prctl: reject PR_SET_MDWE on pre-ARMv6 + - tmpfs: fix race on handling dquot rbtree + - btrfs: validate device maj:min during open + - btrfs: fix race in read_extent_buffer_pages() + - btrfs: zoned: don't skip block groups with 100% zone unusable + - btrfs: zoned: use zone aware sb location for scrub + - btrfs: zoned: fix use-after-free in do_zone_finish() + - wifi: mac80211: check/clear fast rx for non-4addr sta VLAN changes + - wifi: cfg80211: add a flag to disable wireless extensions + - wifi: iwlwifi: mvm: disable MLO for the time being + - wifi: iwlwifi: fw: don't always use FW dump trig + - wifi: iwlwifi: mvm: handle debugfs names more carefully + - Revert "drm/amd/display: Fix sending VSC (+ colorimetry) packets for DP/eDP + displays without PSR" + - fbdev: Select I/O-memory framebuffer ops for SBus + - exec: Fix NOMMU linux_binprm::exec in transfer_args_to_stack() + - hexagon: vmlinux.lds.S: handle attributes section + - mm: cachestat: fix two shmem bugs + - selftests/mm: sigbus-wp test requires UFFD_FEATURE_WP_HUGETLBFS_SHMEM + - selftests/mm: fix ARM related issue with fork after pthread_create + - mmc: sdhci-omap: re-tuning is needed after a pm transition to support emmc + HS200 mode + - mmc: core: Initialize mmc_blk_ioc_data + - mmc: core: Avoid negative index with array access + - sdhci-of-dwcmshc: disable PM runtime in dwcmshc_remove() + - block: Do not force full zone append completion in req_bio_endio() + - thermal: devfreq_cooling: Fix perf state when calculate dfc res_util + - Revert "thermal: core: Don't update trip points inside the hysteresis range" + - nouveau/dmem: handle kcalloc() allocation failure + - net: ll_temac: platform_get_resource replaced by wrong function + - net: wan: framer: Add missing static inline qualifiers + - net: phy: qcom: at803x: fix kernel panic with at8031_probe + - drm/xe/query: fix gt_id bounds check + - drm/dp: Fix divide-by-zero regression on DP MST unplug with nouveau + - drm/vmwgfx: Create debugfs ttm_resource_manager entry only if needed + - drm/amdkfd: fix TLB flush after unmap for GFX9.4.2 + - drm/amdgpu: fix deadlock while reading mqd from debugfs + - drm/amd/display: Remove MPC rate control logic from DCN30 and above + - drm/amd/display: Set DCN351 BB and IP the same as DCN35 + - drm/i915/hwmon: Fix locking inversion in sysfs getter + - drm/i915/vma: Fix UAF on destroy against retire race + - drm/i915/bios: Tolerate devdata==NULL in + intel_bios_encoder_supports_dp_dual_mode() + - drm/i915/vrr: Generate VRR "safe window" for DSB + - drm/i915/dsi: Go back to the previous INIT_OTP/DISPLAY_ON order, mostly + - drm/i915/dsb: Fix DSB vblank waits when using VRR + - drm/i915: Do not match JSL in ehl_combo_pll_div_frac_wa_needed() + - drm/i915: Pre-populate the cursor physical dma address + - drm/i915/gt: Reset queue_priority_hint on parking + - drm/amd/display: Fix bounds check for dcn35 DcfClocks + - Bluetooth: hci_sync: Fix not checking error on hci_cmd_sync_cancel_sync + - mtd: spinand: Add support for 5-byte IDs + - Revert "usb: phy: generic: Get the vbus supply" + - usb: cdc-wdm: close race between read and workqueue + - usb: misc: ljca: Fix double free in error handling path + - USB: UAS: return ENODEV when submit urbs fail with device not attached + - vfio/pds: Make sure migration file isn't accessed after reset + - ring-buffer: Make wake once of ring_buffer_wait() more robust + - btrfs: fix extent map leak in unexpected scenario at unpin_extent_cache() + - ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs + - scsi: ufs: qcom: Provide default cycles_in_1us value + - scsi: sd: Fix TCG OPAL unlock on system resume + - scsi: core: Fix unremoved procfs host directory regression + - staging: vc04_services: changen strncpy() to strscpy_pad() + - staging: vc04_services: fix information leak in create_component() + - genirq: Introduce IRQF_COND_ONESHOT and use it in pinctrl-amd + - usb: dwc3: Properly set system wakeup + - USB: core: Fix deadlock in usb_deauthorize_interface() + - USB: core: Add hub_get() and hub_put() routines + - USB: core: Fix deadlock in port "disable" sysfs attribute + - usb: dwc2: host: Fix remote wakeup from hibernation + - usb: dwc2: host: Fix hibernation flow + - usb: dwc2: host: Fix ISOC flow in DDMA mode + - usb: dwc2: gadget: Fix exiting from clock gating + - usb: dwc2: gadget: LPM flow fix + - usb: udc: remove warning when queue disabled ep + - usb: typec: ucsi: Fix race between typec_switch and role_switch + - usb: typec: tcpm: fix double-free issue in tcpm_port_unregister_pd() + - usb: typec: tcpm: Correct port source pdo array in pd_set callback + - usb: typec: tcpm: Update PD of Type-C port upon pd_set + - usb: typec: Return size of buffer if pd_set operation succeeds + - usb: typec: ucsi: Clear EVENT_PENDING under PPM lock + - usb: typec: ucsi: Ack unsupported commands + - usb: typec: ucsi_acpi: Refactor and fix DELL quirk + - usb: typec: ucsi: Clear UCSI_CCI_RESET_COMPLETE before reset + - scsi: qla2xxx: Prevent command send on chip reset + - scsi: qla2xxx: Fix N2N stuck connection + - scsi: qla2xxx: Split FCE|EFT trace control + - scsi: qla2xxx: Update manufacturer detail + - scsi: qla2xxx: NVME|FCP prefer flag not being honored + - scsi: qla2xxx: Fix command flush on cable pull + - scsi: qla2xxx: Fix double free of the ha->vp_map pointer + - scsi: qla2xxx: Fix double free of fcport + - scsi: qla2xxx: Change debug message during driver unload + - scsi: qla2xxx: Delay I/O Abort on PCI error + - x86/bugs: Fix the SRSO mitigation on Zen3/4 + - crash: use macro to add crashk_res into iomem early for specific arch + - drm/amd/display: fix IPX enablement + - x86/bugs: Use fixed addressing for VERW operand + - Revert "x86/bugs: Use fixed addressing for VERW operand" + - usb: dwc3: pci: Drop duplicate ID + - scsi: lpfc: Correct size for cmdwqe/rspwqe for memset() + - scsi: lpfc: Correct size for wqe for memset() + - scsi: libsas: Add a helper sas_get_sas_addr_and_dev_type() + - scsi: libsas: Fix disk not being scanned in after being removed + - perf/x86/amd/core: Update and fix stalled-cycles-* events for Zen 2 and + later + - x86/sev: Skip ROM range scans and validation for SEV-SNP guests + - tools/resolve_btfids: fix build with musl libc + - drm/amdgpu: fix use-after-free bug + - drm/sched: fix null-ptr-deref in init entity + - Linux 6.8.3 + - [Config] updateconfigs following v6.8.3 import + + * Noble update: v6.8.3 upstream stable release (LP: #2060531) // + [Ubuntu-24.04] Hugepage memory is not getting released even after destroying + the guest! (LP: #2062556) + - block: Fix page refcounts for unaligned buffers in __bio_release_pages() + + * [SPR][EMR][GNR] TDX: efi: TD Measurement support for kernel cmdline/initrd + sections from EFI stub (LP: #2060130) + - efi/libstub: Use TPM event typedefs from the TCG PC Client spec + - efi/tpm: Use symbolic GUID name from spec for final events table + - efi/libstub: Add Confidential Computing (CC) measurement typedefs + - efi/libstub: Measure into CC protocol if TCG2 protocol is absent + - efi/libstub: Add get_event_log() support for CC platforms + - x86/efistub: Remap kernel text read-only before dropping NX attribute + + * Fix acpi_power_meter accessing IPMI region before it's ready (LP: #2059263) + - ACPI: IPMI: Add helper to wait for when SMI is selected + - hwmon: (acpi_power_meter) Ensure IPMI space handler is ready on Dell systems + + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + + * alsa/realtek: adjust max output valume for headphone on 2 LG machines + (LP: #2058573) + - ALSA: hda/realtek: fix the hp playback volume issue for LG machines + + * Noble update: v6.8.2 upstream stable release (LP: #2060097) + - do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak + - workqueue.c: Increase workqueue name length + - workqueue: Move pwq->max_active to wq->max_active + - workqueue: Factor out pwq_is_empty() + - workqueue: Replace pwq_activate_inactive_work() with [__]pwq_activate_work() + - workqueue: Move nr_active handling into helpers + - workqueue: Make wq_adjust_max_active() round-robin pwqs while activating + - workqueue: RCU protect wq->dfl_pwq and implement accessors for it + - workqueue: Introduce struct wq_node_nr_active + - workqueue: Implement system-wide nr_active enforcement for unbound + workqueues + - workqueue: Don't call cpumask_test_cpu() with -1 CPU in + wq_update_node_max_active() + - iomap: clear the per-folio dirty bits on all writeback failures + - fs: Fix rw_hint validation + - io_uring: remove looping around handling traditional task_work + - io_uring: remove unconditional looping in local task_work handling + - s390/dasd: Use dev_*() for device log messages + - s390/dasd: fix double module refcount decrement + - fs/hfsplus: use better @opf description + - md: fix kmemleak of rdev->serial + - rcu/exp: Fix RCU expedited parallel grace period kworker allocation failure + recovery + - rcu/exp: Handle RCU expedited grace period kworker allocation failure + - fs/select: rework stack allocation hack for clang + - block: fix deadlock between bd_link_disk_holder and partition scan + - md: Don't clear MD_CLOSING when the raid is about to stop + - kunit: Setup DMA masks on the kunit device + - ovl: Always reject mounting over case-insensitive directories + - kunit: test: Log the correct filter string in executor_test + - lib/cmdline: Fix an invalid format specifier in an assertion msg + - lib: memcpy_kunit: Fix an invalid format specifier in an assertion msg + - time: test: Fix incorrect format specifier + - rtc: test: Fix invalid format specifier. + - net: test: Fix printf format specifier in skb_segment kunit test + - drm/xe/tests: Fix printf format specifiers in xe_migrate test + - drm: tests: Fix invalid printf format specifiers in KUnit tests + - md/raid1: factor out helpers to add rdev to conf + - md/raid1: record nonrot rdevs while adding/removing rdevs to conf + - md/raid1: fix choose next idle in read_balance() + - io_uring/net: unify how recvmsg and sendmsg copy in the msghdr + - io_uring/net: move receive multishot out of the generic msghdr path + - io_uring/net: fix overflow check in io_recvmsg_mshot_prep() + - nvme: host: fix double-free of struct nvme_id_ns in ns_update_nuse() + - aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts + - x86/mm: Ensure input to pfn_to_kaddr() is treated as a 64-bit type + - x86/resctrl: Remove hard-coded memory bandwidth limit + - x86/resctrl: Read supported bandwidth sources from CPUID + - x86/resctrl: Implement new mba_MBps throttling heuristic + - x86/sme: Fix memory encryption setting if enabled by default and not + overridden + - timekeeping: Fix cross-timestamp interpolation on counter wrap + - timekeeping: Fix cross-timestamp interpolation corner case decision + - timekeeping: Fix cross-timestamp interpolation for non-x86 + - x86/asm: Remove the __iomem annotation of movdir64b()'s dst argument + - sched/fair: Take the scheduling domain into account in select_idle_smt() + - sched/fair: Take the scheduling domain into account in select_idle_core() + - wifi: ath10k: fix NULL pointer dereference in + ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev() + - wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is disabled + - wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is disabled + - wifi: b43: Stop correct queue in DMA worker when QoS is disabled + - wifi: b43: Disable QoS for bcm4331 + - wifi: wilc1000: fix declarations ordering + - wifi: wilc1000: fix RCU usage in connect path + - wifi: ath11k: add support to select 6 GHz regulatory type + - wifi: ath11k: store cur_regulatory_info for each radio + - wifi: ath11k: fix a possible dead lock caused by ab->base_lock + - wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work + - wifi: wilc1000: do not realloc workqueue everytime an interface is added + - wifi: wilc1000: fix multi-vif management when deleting a vif + - wifi: mwifiex: debugfs: Drop unnecessary error check for + debugfs_create_dir() + - ARM: dts: renesas: r8a73a4: Fix external clocks and clock rate + - arm64: dts: qcom: x1e80100: drop qcom,drv-count + - arm64: dts: qcom: sc8180x: Hook up VDD_CX as GCC parent domain + - arm64: dts: qcom: sc8180x: Fix up big CPU idle state entry latency + - arm64: dts: qcom: sc8180x: Add missing CPU off state + - arm64: dts: qcom: sc8180x: Fix eDP PHY power-domains + - arm64: dts: qcom: sc8180x: Don't hold MDP core clock at FMAX + - arm64: dts: qcom: sc8180x: Require LOW_SVS vote for MMCX if DISPCC is on + - arm64: dts: qcom: sc8180x: Add missing CPU<->MDP_CFG path + - arm64: dts: qcom: sc8180x: Shrink aoss_qmp register space size + - cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value + - cpufreq: mediatek-hw: Wait for CPU supplies before probing + - sock_diag: annotate data-races around sock_diag_handlers[family] + - inet_diag: annotate data-races around inet_diag_table[] + - bpftool: Silence build warning about calloc() + - selftests/bpf: Fix potential premature unload in bpf_testmod + - libbpf: Apply map_set_def_max_entries() for inner_maps on creation + - selftest/bpf: Add map_in_maps with BPF_MAP_TYPE_PERF_EVENT_ARRAY values + - bpftool: Fix wrong free call in do_show_link + - wifi: ath12k: Fix issues in channel list update + - selftests/bpf: Fix the flaky tc_redirect_dtime test + - selftests/bpf: Wait for the netstamp_needed_key static key to be turned on + - wifi: cfg80211: add RNR with reporting AP information + - wifi: mac80211: use deflink and fix typo in link ID check + - wifi: iwlwifi: change link id in time event to s8 + - af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc(). + - arm64: dts: qcom: sm8450: Add missing interconnects to serial + - soc: qcom: socinfo: rename PM2250 to PM4125 + - arm64: dts: qcom: sc7280: Add static properties to cryptobam + - arm64: dts: qcom: qcm6490-fairphone-fp5: Add missing reserved-memory + - arm64: dts: qcom: sdm845-oneplus-common: improve DAI node naming + - arm64: dts: qcom: rename PM2250 to PM4125 + - cpufreq: mediatek-hw: Don't error out if supply is not found + - libbpf: Fix faccessat() usage on Android + - libbpf: fix __arg_ctx type enforcement for perf_event programs + - pmdomain: qcom: rpmhpd: Drop SA8540P gfx.lvl + - arm64: dts: qcom: sa8540p: Drop gfx.lvl as power-domain for gpucc + - arm64: dts: renesas: r8a779g0: Restore sort order + - arm64: dts: renesas: r8a779g0: Add missing SCIF_CLK2 + - selftests/bpf: Disable IPv6 for lwt_redirect test + - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on OSM-S i.MX8MM + - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on SL/BL i.MX8MM + - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL + OSM-S board + - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL + board + - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL + OSM-S board + - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL + board + - arm64: dts: imx8mm-kontron: Fix interrupt for RTC on OSM-S i.MX8MM module + - arm64: dts: imx8qm: Align edma3 power-domains resources indentation + - arm64: dts: imx8qm: Correct edma3 power-domains and interrupt numbers + - libbpf: Add missing LIBBPF_API annotation to libbpf_set_memlock_rlim API + - wifi: ath9k: delay all of ath9k_wmi_event_tasklet() until init is complete + - wifi: ath11k: change to move WMI_VDEV_PARAM_SET_HEMU_MODE before + WMI_PEER_ASSOC_CMDID + - wifi: ath12k: fix fetching MCBC flag for QCN9274 + - wifi: iwlwifi: mvm: report beacon protection failures + - wifi: iwlwifi: dbg-tlv: ensure NUL termination + - wifi: iwlwifi: acpi: fix WPFC reading + - wifi: iwlwifi: mvm: initialize rates in FW earlier + - wifi: iwlwifi: fix EWRD table validity check + - wifi: iwlwifi: mvm: d3: fix IPN byte order + - wifi: iwlwifi: always have 'uats_enabled' + - wifi: iwlwifi: mvm: fix the TLC command after ADD_STA + - wifi: iwlwifi: read BIOS PNVM only for non-Intel SKU + - gpio: vf610: allow disabling the vf610 driver + - selftests/bpf: trace_helpers.c: do not use poisoned type + - bpf: make sure scalar args don't accept __arg_nonnull tag + - bpf: don't emit warnings intended for global subprogs for static subprogs + - arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS + - pwm: atmel-hlcdc: Fix clock imbalance related to suspend support + - net: blackhole_dev: fix build warning for ethh set but not used + - spi: consolidate setting message->spi + - spi: move split xfers for CS_WORD emulation + - arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node + - arm64: dts: ti: k3-j721s2: Fix power domain for VTM node + - arm64: dts: ti: k3-j784s4: Fix power domain for VTM node + - wifi: ath11k: initialize rx_mcs_80 and rx_mcs_160 before use + - wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer() + - arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP + - libbpf: fix return value for PERF_EVENT __arg_ctx type fix up check + - arm64: dts: ti: k3-am62p-mcu/wakeup: Disable MCU and wakeup R5FSS nodes + - arm64: dts: qcom: x1e80100-qcp: Fix supplies for LDOs 3E and 2J + - libbpf: Use OPTS_SET() macro in bpf_xdp_query() + - wifi: wfx: fix memory leak when starting AP + - arm64: dts: qcom: qcm2290: declare VLS CLAMP register for USB3 PHY + - arm64: dts: qcom: sm6115: declare VLS CLAMP register for USB3 PHY + - arm64: dts: qcom: sm8650: Fix UFS PHY clocks + - wifi: ath12k: fix incorrect logic of calculating vdev_stats_id + - printk: nbcon: Relocate 32bit seq macros + - printk: ringbuffer: Do not skip non-finalized records with prb_next_seq() + - printk: Wait for all reserved records with pr_flush() + - printk: Add this_cpu_in_panic() + - printk: ringbuffer: Cleanup reader terminology + - printk: ringbuffer: Skip non-finalized records in panic + - printk: Disable passing console lock owner completely during panic() + - pwm: sti: Fix capture for st,pwm-num-chan < st,capture-num-chan + - tools/resolve_btfids: Refactor set sorting with types from btf_ids.h + - tools/resolve_btfids: Fix cross-compilation to non-host endianness + - wifi: iwlwifi: support EHT for WH + - wifi: iwlwifi: properly check if link is active + - wifi: iwlwifi: mvm: fix erroneous queue index mask + - wifi: iwlwifi: mvm: don't set the MFP flag for the GTK + - wifi: iwlwifi: mvm: don't set replay counters to 0xff + - s390/pai: fix attr_event_free upper limit for pai device drivers + - s390/vdso: drop '-fPIC' from LDFLAGS + - arm64: dts: qcom: qcm6490-idp: Correct the voltage setting for vph_pwr + - arm64: dts: qcom: qcs6490-rb3gen2: Correct the voltage setting for vph_pwr + - selftests: forwarding: Add missing config entries + - selftests: forwarding: Add missing multicast routing config entries + - arm64: dts: qcom: sm6115: drop pipe clock selection + - ipv6: mcast: remove one synchronize_net() barrier in ipv6_mc_down() + - arm64: dts: mt8183: Move CrosEC base detection node to kukui-based DTs + - arm64: dts: mediatek: mt7986: fix reference to PWM in fan node + - arm64: dts: mediatek: mt7986: drop crypto's unneeded/invalid clock name + - arm64: dts: mediatek: mt7986: fix SPI bus width properties + - arm64: dts: mediatek: mt7986: fix SPI nodename + - arm64: dts: mediatek: mt7986: drop "#clock-cells" from PWM + - arm64: dts: mediatek: mt7986: add "#reset-cells" to infracfg + - arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node + - arm64: dts: mediatek: mt8192: fix vencoder clock name + - arm64: dts: mediatek: mt8186: fix VENC power domain clocks + - arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes + - can: m_can: Start/Cancel polling timer together with interrupts + - wifi: iwlwifi: mvm: Fix the listener MAC filter flags + - bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly + - arm64: dts: qcom: sdm845: Use the Low Power Island CX/MX for SLPI + - soc: qcom: llcc: Check return value on Broadcast_OR reg read + - ARM: dts: qcom: msm8974: correct qfprom node size + - arm64: dts: mediatek: mt8186: Add missing clocks to ssusb power domains + - arm64: dts: mediatek: mt8186: Add missing xhci clock to usb controllers + - arm64: dts: ti: am65x: Fix dtbs_install for Rocktech OLDI overlay + - cpufreq: qcom-hw: add CONFIG_COMMON_CLK dependency + - wifi: wilc1000: prevent use-after-free on vif when cleaning up all + interfaces + - pwm: dwc: use pm_sleep_ptr() macro + - arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number + - arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number + - arm64: dts: ti: k3-am62-main: disable usb lpm + - ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit() + - bus: tegra-aconnect: Update dependency to ARCH_TEGRA + - iommu/amd: Mark interrupt as managed + - wifi: brcmsmac: avoid function pointer casts + - arm64: dts: qcom: sdm845-db845c: correct PCIe wake-gpios + - arm64: dts: qcom: sm8150: correct PCIe wake-gpios + - powercap: dtpm_cpu: Fix error check against freq_qos_add_request() + - net: ena: Remove ena_select_queue + - arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and + mcu_uart0 + - arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from + mcu_uart0 + - arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS + in wkup_uart0 + - arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0 + - arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC + - arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow + - arm64: dts: ti: Add common1 register space for AM65x SoC + - arm64: dts: ti: Add common1 register space for AM62x SoC + - firmware: arm_scmi: Fix double free in SMC transport cleanup path + - wifi: cfg80211: set correct param change count in ML element + - arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux + - arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl + - arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS + - wifi: wilc1000: revert reset line logic flip + - ARM: dts: arm: realview: Fix development chip ROM compatible value + - memory: tegra: Correct DLA client names + - wifi: mt76: mt7996: fix fw loading timeout + - wifi: mt76: mt7925: fix connect to 80211b mode fail in 2Ghz band + - wifi: mt76: mt7925: fix SAP no beacon issue in 5Ghz and 6Ghz band + - wifi: mt76: mt7925: fix mcu query command fail + - wifi: mt76: mt7925: fix wmm queue mapping + - wifi: mt76: mt7925: fix fw download fail + - wifi: mt76: mt7925: fix WoW failed in encrypted mode + - wifi: mt76: mt7925: fix the wrong header translation config + - wifi: mt76: mt7925: add flow to avoid chip bt function fail + - wifi: mt76: mt7925: add support to set ifs time by mcu command + - wifi: mt76: mt7925: update PCIe DMA settings + - wifi: mt76: mt7996: check txs format before getting skb by pid + - wifi: mt76: mt7996: fix TWT issues + - wifi: mt76: mt7996: fix incorrect interpretation of EHT MCS caps + - wifi: mt76: mt7996: fix HE beamformer phy cap for station vif + - wifi: mt76: mt7996: fix efuse reading issue + - wifi: mt76: mt7996: fix HIF_TXD_V2_1 value + - wifi: mt76: mt792x: fix ethtool warning + - wifi: mt76: mt7921e: fix use-after-free in free_irq() + - wifi: mt76: mt7925e: fix use-after-free in free_irq() + - wifi: mt76: mt7921: fix incorrect type conversion for CLC command + - wifi: mt76: mt792x: fix a potential loading failure of the 6Ghz channel + config from ACPI + - wifi: mt76: fix the issue of missing txpwr settings from ch153 to ch177 + - arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes + - arm64: dts: renesas: r9a08g045: Add missing interrupts to IRQC node + - arm64: dts: renesas: rzg3s-smarc-som: Guard Ethernet IRQ GPIO hogs + - arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes + - arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes + - net: mctp: copy skb ext data when fragmenting + - pstore: inode: Only d_invalidate() is needed + - arm64: dts: allwinner: h6: Add RX DMA channel for SPDIF + - ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address + - ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node + - arm64: dts: imx8mp: Set SPI NOR to max 40 MHz on Data Modul i.MX8M Plus eDM + SBC + - arm64: dts: imx8mp-evk: Fix hdmi@3d node + - regulator: userspace-consumer: add module device table + - gpiolib: Pass consumer device through to core in + devm_fwnode_gpiod_get_index() + - arm64: dts: marvell: reorder crypto interrupts on Armada SoCs + - ACPI: resource: Do IRQ override on Lunnen Ground laptops + - ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override + - ACPI: scan: Fix device check notification handling + - arm64: dts: rockchip: add missing interrupt-names for rk356x vdpu + - arm64: dts: rockchip: fix reset-names for rk356x i2s2 controller + - arm64: dts: rockchip: drop rockchip,trcm-sync-tx-only from rk3588 i2s + - objtool: Fix UNWIND_HINT_{SAVE,RESTORE} across basic blocks + - x86, relocs: Ignore relocations in .notes section + - SUNRPC: fix a memleak in gss_import_v2_context + - SUNRPC: fix some memleaks in gssx_dec_option_array + - arm64: dts: qcom: sm8550: Fix SPMI channels size + - arm64: dts: qcom: sm8650: Fix SPMI channels size + - mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the .remove + function + - ACPI: CPPC: enable AMD CPPC V2 support for family 17h processors + - btrfs: fix race when detecting delalloc ranges during fiemap + - wifi: rtw88: 8821cu: Fix firmware upload fail + - wifi: rtw88: 8821c: Fix beacon loss and disconnect + - wifi: rtw88: 8821c: Fix false alarm count + - wifi: brcm80211: handle pmk_op allocation failure + - riscv: dts: starfive: jh7100: fix root clock names + - PCI: Make pci_dev_is_disconnected() helper public for other drivers + - iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected + - iommu/vt-d: Use rbtree to track iommu probed devices + - iommu/vt-d: Improve ITE fault handling if target device isn't present + - iommu/vt-d: Use device rbtree in iopf reporting path + - iommu: Add static iommu_ops->release_domain + - iommu/vt-d: Fix NULL domain on device release + - igc: Fix missing time sync events + - igb: Fix missing time sync events + - ice: fix stats being updated by way too large values + - Bluetooth: Remove HCI_POWER_OFF_TIMEOUT + - Bluetooth: mgmt: Remove leftover queuing of power_off work + - Bluetooth: Remove superfluous call to hci_conn_check_pending() + - Bluetooth: Remove BT_HS + - Bluetooth: hci_event: Fix not indicating new connection for BIG Sync + - Bluetooth: hci_qca: don't use IS_ERR_OR_NULL() with gpiod_get_optional() + - Bluetooth: hci_core: Cancel request on command timeout + - Bluetooth: hci_sync: Fix overwriting request callback + - Bluetooth: hci_h5: Add ability to allocate memory for private data + - Bluetooth: btrtl: fix out of bounds memory access + - Bluetooth: hci_core: Fix possible buffer overflow + - Bluetooth: msft: Fix memory leak + - Bluetooth: btusb: Fix memory leak + - Bluetooth: af_bluetooth: Fix deadlock + - Bluetooth: fix use-after-free in accessing skb after sending it + - sr9800: Add check for usbnet_get_endpoints + - s390/cache: prevent rebuild of shared_cpu_list + - bpf: Fix DEVMAP_HASH overflow check on 32-bit arches + - bpf: Fix hashtab overflow check on 32-bit arches + - bpf: Fix stackmap overflow check on 32-bit arches + - net: dsa: microchip: make sure drive strength configuration is not lost by + soft reset + - dpll: spec: use proper enum for pin capabilities attribute + - iommu: Fix compilation without CONFIG_IOMMU_INTEL + - ipv6: fib6_rules: flush route cache when rule is changed + - net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv() + - octeontx2-af: Fix devlink params + - net: phy: fix phy_get_internal_delay accessing an empty array + - dpll: fix dpll_xa_ref_*_del() for multiple registrations + - net: hns3: fix wrong judgment condition issue + - net: hns3: fix kernel crash when 1588 is received on HIP08 devices + - net: hns3: fix port duplex configure error in IMP reset + - Bluetooth: Fix eir name length + - net: phy: dp83822: Fix RGMII TX delay configuration + - erofs: fix lockdep false positives on initializing erofs_pseudo_mnt + - OPP: debugfs: Fix warning around icc_get_name() + - tcp: fix incorrect parameter validation in the do_tcp_getsockopt() function + - ipmr: fix incorrect parameter validation in the ip_mroute_getsockopt() + function + - l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt() + function + - udp: fix incorrect parameter validation in the udp_lib_getsockopt() function + - net: kcm: fix incorrect parameter validation in the kcm_getsockopt) function + - net/x25: fix incorrect parameter validation in the x25_getsockopt() function + - devlink: Fix length of eswitch inline-mode + - r8152: fix unknown device for choose_configuration + - nfp: flower: handle acti_netdevs allocation failure + - bpf: hardcode BPF_PROG_PACK_SIZE to 2MB * num_possible_nodes() + - dm raid: fix false positive for requeue needed during reshape + - dm: call the resume method on internal suspend + - fbdev/simplefb: change loglevel when the power domains cannot be parsed + - drm/tegra: dsi: Add missing check for of_find_device_by_node + - drm/tegra: dpaux: Fix PM disable depth imbalance in tegra_dpaux_probe + - drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe() + - drm/tegra: dsi: Fix missing pm_runtime_disable() in the error handling path + of tegra_dsi_probe() + - drm/tegra: hdmi: Fix some error handling paths in tegra_hdmi_probe() + - drm/tegra: rgb: Fix some error handling paths in tegra_dc_rgb_probe() + - drm/tegra: rgb: Fix missing clk_put() in the error handling paths of + tegra_dc_rgb_probe() + - drm/tegra: output: Fix missing i2c_put_adapter() in the error handling paths + of tegra_output_probe() + - drm/rockchip: inno_hdmi: Fix video timing + - drm: Don't treat 0 as -1 in drm_fixp2int_ceil + - drm/vkms: Avoid reading beyond LUT array + - drm/vmwgfx: fix a memleak in vmw_gmrid_man_get_node + - drm/rockchip: lvds: do not overwrite error code + - drm/rockchip: lvds: do not print scary message when probing defer + - drm/panel-edp: use put_sync in unprepare + - drm/lima: fix a memleak in lima_heap_alloc + - ASoC: amd: acp: Add missing error handling in sof-mach + - ASoC: SOF: amd: Fix memory leak in amd_sof_acp_probe() + - ASoC: SOF: core: Skip firmware test for custom loaders + - ASoC: SOF: amd: Compute file paths on firmware load + - soundwire: stream: add missing const to Documentation + - dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA + - media: tc358743: register v4l2 async device only after successful setup + - media: cadence: csi2rx: use match fwnode for media link + - PCI/DPC: Print all TLP Prefixes, not just the first + - perf record: Fix possible incorrect free in record__switch_output() + - perf record: Check conflict between '--timestamp-filename' option and pipe + mode before recording + - HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd + - drm/amd/display: Fix a potential buffer overflow in 'dp_dsc_clock_en_read()' + - perf pmu: Treat the msr pmu as software + - crypto: qat - avoid memcpy() overflow warning + - ALSA: hda: cs35l41: Set Channel Index correctly when system is missing _DSD + - drm/amd/display: Fix potential NULL pointer dereferences in + 'dcn10_set_output_transfer_func()' + - ASoC: sh: rz-ssi: Fix error message print + - drm/vmwgfx: Fix vmw_du_get_cursor_mob fencing of newly-created MOBs + - clk: renesas: r8a779g0: Fix PCIe clock name + - pinctrl: renesas: rzg2l: Fix locking in rzg2l_dt_subnode_to_map() + - pinctrl: renesas: r8a779g0: Add missing SCIF_CLK2 pin group/function + - clk: samsung: exynos850: Propagate SPI IPCLK rate change + - media: v4l2: cci: print leading 0 on error + - perf evsel: Fix duplicate initialization of data->id in + evsel__parse_sample() + - perf bpf: Clean up the generated/copied vmlinux.h + - clk: meson: Add missing clocks to axg_clk_regmaps + - media: em28xx: annotate unchecked call to media_device_register() + - media: v4l2-tpg: fix some memleaks in tpg_alloc + - media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity + - media: dt-bindings: techwell,tw9900: Fix port schema ref + - mtd: spinand: esmt: Extend IDs to 5 bytes + - media: edia: dvbdev: fix a use-after-free + - pinctrl: mediatek: Drop bogus slew rate register range for MT8186 + - pinctrl: mediatek: Drop bogus slew rate register range for MT8192 + - drm/amdgpu: Fix potential out-of-bounds access in + 'amdgpu_discovery_reg_base_init()' + - clk: qcom: reset: Commonize the de/assert functions + - clk: qcom: reset: Ensure write completion on reset de/assertion + - quota: Fix potential NULL pointer dereference + - quota: Fix rcu annotations of inode dquot pointers + - quota: Properly annotate i_dquot arrays with __rcu + - ASoC: Intel: ssp-common: Add stub for sof_ssp_get_codec_name + - PCI/P2PDMA: Fix a sleeping issue in a RCU read section + - PCI: switchtec: Fix an error handling path in switchtec_pci_probe() + - crypto: xilinx - call finalize with bh disabled + - drivers/ps3: select VIDEO to provide cmdline functions + - perf thread_map: Free strlist on normal path in thread_map__new_by_tid_str() + - perf srcline: Add missed addr2line closes + - dt-bindings: msm: qcom, mdss: Include ommited fam-b compatible + - drm/msm/dpu: fix the programming of INTF_CFG2_DATA_HCTL_EN + - drm/msm/dpu: Only enable DSC_MODE_MULTIPLEX if dsc_merge is enabled + - drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode() + - drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini() + - clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks + - clk: renesas: r8a779f0: Correct PFC/GPIO parent clock + - clk: renesas: r9a07g04[34]: Use SEL_SDHI1_STS status configuration for SD1 + mux + - ALSA: seq: fix function cast warnings + - perf expr: Fix "has_event" function for metric style events + - perf stat: Avoid metric-only segv + - perf metric: Don't remove scale from counts + - ASoC: meson: aiu: fix function pointer type mismatch + - ASoC: meson: t9015: fix function pointer type mismatch + - powerpc: Force inlining of arch_vmap_p{u/m}d_supported() + - ASoC: SOF: Add some bounds checking to firmware data + - drm: ci: use clk_ignore_unused for apq8016 + - NTB: fix possible name leak in ntb_register_device() + - media: cedrus: h265: Fix configuring bitstream size + - media: sun8i-di: Fix coefficient writes + - media: sun8i-di: Fix power on/off sequences + - media: sun8i-di: Fix chroma difference threshold + - staging: media: starfive: Set 16 bpp for capture_raw device + - media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak + - media: go7007: add check of return value of go7007_read_addr() + - media: pvrusb2: remove redundant NULL check + - media: videobuf2: Add missing doc comment for waiting_in_dqbuf + - media: pvrusb2: fix pvr2_stream_callback casts + - clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times + - drm/amd/display: Add 'replay' NULL check in 'edp_set_replay_allow_active()' + - drm/panel: boe-tv101wum-nl6: make use of prepare_prev_first + - drm/msm/dpu: finalise global state object + - drm/mediatek: dsi: Fix DSI RGB666 formats and definitions + - PCI: Mark 3ware-9650SE Root Port Extended Tags as broken + - drm/bridge: adv7511: fix crash on irq during probe + - pinctrl: renesas: Allow the compiler to optimize away sh_pfc_pm + - clk: hisilicon: hi3519: Release the correct number of gates in + hi3519_clk_unregister() + - clk: hisilicon: hi3559a: Fix an erroneous devm_kfree() + - clk: mediatek: mt8135: Fix an error handling path in + clk_mt8135_apmixed_probe() + - clk: mediatek: mt7622-apmixedsys: Fix an error handling path in + clk_mt8135_apmixed_probe() + - clk: mediatek: mt8183: Correct parent of CLK_INFRA_SSPM_32K_SELF + - clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical + - drm/tegra: put drm_gem_object ref on error in tegra_fb_create + - tty: mips_ejtag_fdc: Fix passing incompatible pointer type warning + - media: ivsc: csi: Swap SINK and SOURCE pads + - media: i2c: imx290: Fix IMX920 typo + - mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref + - mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a + ref + - perf print-events: make is_event_supported() more robust + - crypto: arm/sha - fix function cast warnings + - crypto: ccp - Avoid discarding errors in psp_send_platform_access_msg() + - crypto: qat - remove unused macros in qat_comp_alg.c + - crypto: qat - removed unused macro in adf_cnv_dbgfs.c + - crypto: qat - avoid division by zero + - crypto: qat - remove double initialization of value + - crypto: qat - fix ring to service map for dcc in 4xxx + - crypto: qat - fix ring to service map for dcc in 420xx + - crypto: jitter - fix CRYPTO_JITTERENTROPY help text + - drm/tidss: Fix initial plane zpos values + - drm/tidss: Fix sync-lost issue with two displays + - clk: imx: imx8mp: Fix SAI_MCLK_SEL definition + - mtd: maps: physmap-core: fix flash size larger than 32-bit + - mtd: rawnand: lpc32xx_mlc: fix irq handler prototype + - mtd: rawnand: brcmnand: exec_op helper functions return type fixes + - ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs + - ASoC: meson: axg-tdm-interface: add frame rate constraint + - drm/msm/a6xx: specify UBWC config for sc7180 + - drm/msm/a7xx: Fix LLC typo + - dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if condition + - perf pmu: Fix a potential memory leak in perf_pmu__lookup() + - HID: amd_sfh: Update HPD sensor structure elements + - HID: amd_sfh: Avoid disabling the interrupt + - drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of atom_get_src_int() + - media: pvrusb2: fix uaf in pvr2_context_set_notify + - media: dvb-frontends: avoid stack overflow warnings with clang + - media: go7007: fix a memleak in go7007_load_encoder + - media: ttpci: fix two memleaks in budget_av_attach + - media: mediatek: vcodec: avoid -Wcast-function-type-strict warning + - arm64: ftrace: Don't forbid CALL_OPS+CC_OPTIMIZE_FOR_SIZE with Clang + - drm/tests: helpers: Include missing drm_drv header + - drm/amd/pm: Fix esm reg mask use to get pcie speed + - gpio: nomadik: fix offset bug in nmk_pmx_set() + - drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip + - mfd: cs42l43: Fix wrong register defaults + - powerpc/32: fix ADB_CUDA kconfig warning + - powerpc/pseries: Fix potential memleak in papr_get_attr() + - powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value checks + - clk: qcom: gcc-ipq5018: fix 'enable_reg' offset of 'gcc_gmac0_sys_clk' + - clk: qcom: gcc-ipq5018: fix 'halt_reg' offset of 'gcc_pcie1_pipe_clk' + - clk: qcom: gcc-ipq5018: fix register offset for GCC_UBI0_AXI_ARES reset + - perf vendor events amd: Fix Zen 4 cache latency events + - drm/msm/dpu: allow certain formats for CDM for DP + - drm/msm/dpu: add division of drm_display_mode's hskew parameter + - media: usbtv: Remove useless locks in usbtv_video_free() + - drm/xe: Fix ref counting leak on page fault + - drm/xe: Replace 'grouped target' in Makefile with pattern rule + - lib/stackdepot: fix first entry having a 0-handle + - lib/stackdepot: off by one in depot_fetch_stack() + - modules: wait do_free_init correctly + - mfd: cs42l43: Fix wrong GPIO_FN_SEL and SPI_CLK_CONFIG1 defaults + - power: supply: mm8013: fix "not charging" detection + - powerpc/embedded6xx: Fix no previous prototype for avr_uart_send() etc. + - powerpc/4xx: Fix warp_gpio_leds build failure + - RISC-V: KVM: Forward SEED CSR access to user space + - leds: aw2013: Unlock mutex before destroying it + - leds: sgm3140: Add missing timer cleanup and flash gpio control + - backlight: hx8357: Fix potential NULL pointer dereference + - backlight: ktz8866: Correct the check for of_property_read_u32 + - backlight: lm3630a: Initialize backlight_properties on init + - backlight: lm3630a: Don't set bl->props.brightness in get_brightness + - backlight: da9052: Fully initialize backlight_properties during probe + - backlight: lm3639: Fully initialize backlight_properties during probe + - backlight: lp8788: Fully initialize backlight_properties during probe + - sparc32: Use generic cmpdi2/ucmpdi2 variants + - mtd: maps: sun_uflash: Declare uflash_devinit static + - sparc32: Do not select GENERIC_ISA_DMA + - sparc32: Fix section mismatch in leon_pci_grpci + - clk: Fix clk_core_get NULL dereference + - clk: zynq: Prevent null pointer dereference caused by kmalloc failure + - PCI: brcmstb: Fix broken brcm_pcie_mdio_write() polling + - cifs: Fix writeback data corruption + - ALSA: hda/realtek: fix ALC285 issues on HP Envy x360 laptops + - ALSA: hda/tas2781: use dev_dbg in system_resume + - ALSA: hda/tas2781: add lock to system_suspend + - ALSA: hda/tas2781: do not reset cur_* values in runtime_suspend + - ALSA: hda/tas2781: do not call pm_runtime_force_* in system_resume/suspend + - ALSA: hda/tas2781: restore power state after system_resume + - ALSA: scarlett2: Fix Scarlett 4th Gen 4i4 low-voltage detection + - ALSA: scarlett2: Fix Scarlett 4th Gen autogain status values + - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range + - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range again + - mips: cm: Convert __mips_cm_l2sync_phys_base() to weak function + - platform/x86/intel/pmc/lnl: Remove SSRAM support + - platform/x86/intel/pmc/arl: Put GNA device in D3 + - platform/x86/amd/pmf: Do not use readl() for policy buffer access + - ALSA: usb-audio: Stop parsing channels bits when all channels are found. + - phy: qcom: qmp-usb: split USB-C PHY driver + - phy: qcom: qmp-usbc: add support for the Type-C handling + - phy: qcom: qmp-usbc: handle CLAMP register in a correct way + - scsi: hisi_sas: Fix a deadlock issue related to automatic dump + - RDMA/irdma: Remove duplicate assignment + - RDMA/srpt: Do not register event handler until srpt device is fully setup + - f2fs: compress: fix to guarantee persisting compressed blocks by CP + - f2fs: compress: fix to cover normal cluster write with cp_rwsem + - f2fs: compress: fix to check unreleased compressed cluster + - f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode + - f2fs: fix to remove unnecessary f2fs_bug_on() to avoid panic + - f2fs: zone: fix to wait completion of last bio in zone correctly + - f2fs: fix NULL pointer dereference in f2fs_submit_page_write() + - f2fs: compress: fix to cover f2fs_disable_compressed_file() w/ i_sem + - f2fs: fix to avoid potential panic during recovery + - scsi: csiostor: Avoid function pointer casts + - i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling + - RDMA/hns: Fix mis-modifying default congestion control algorithm + - RDMA/device: Fix a race between mad_client and cm_client init + - RDMA/rtrs-clt: Check strnlen return len in sysfs mpath_policy_store() + - scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn + - f2fs: fix to create selinux label during whiteout initialization + - f2fs: compress: fix to check zstd compress level correctly in mount option + - net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr() + - NFSv4.2: fix nfs4_listxattr kernel BUG at mm/usercopy.c:102 + - NFSv4.2: fix listxattr maximum XDR buffer size + - f2fs: compress: fix to check compress flag w/ .i_sem lock + - f2fs: check number of blocks in a current section + - watchdog: starfive: Check pm_runtime_enabled() before decrementing usage + counter + - watchdog: stm32_iwdg: initialize default timeout + - f2fs: fix to use correct segment type in f2fs_allocate_data_block() + - f2fs: ro: compress: fix to avoid caching unaligned extent + - RDMA/mana_ib: Fix bug in creation of dma regions + - RDMA/mana_ib: Introduce mdev_to_gc helper function + - RDMA/mana_ib: Introduce mana_ib_get_netdev helper function + - RDMA/mana_ib: Introduce mana_ib_install_cq_cb helper function + - RDMA/mana_ib: Use virtual address in dma regions for MRs + - Input: iqs7222 - add support for IQS7222D v1.1 and v1.2 + - NFS: Fix nfs_netfs_issue_read() xarray locking for writeback interrupt + - NFS: Fix an off by one in root_nfs_cat() + - NFSv4.1/pnfs: fix NFS with TLS in pnfs + - ACPI: HMAT: Remove register of memory node for generic target + - f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks + - f2fs: compress: fix reserve_cblocks counting error when out of space + - f2fs: fix to truncate meta inode pages forcely + - f2fs: zone: fix to remove pow2 check condition for zoned block device + - cxl: Fix the incorrect assignment of SSLBIS entry pointer initial location + - perf/x86/amd/core: Avoid register reset when CPU is dead + - afs: Revert "afs: Hide silly-rename files from userspace" + - afs: Don't cache preferred address + - afs: Fix occasional rmdir-then-VNOVNODE with generic/011 + - f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault + - nfs: fix panic when nfs4_ff_layout_prepare_ds() fails + - ovl: relax WARN_ON in ovl_verify_area() + - io_uring/net: correct the type of variable + - remoteproc: stm32: Fix incorrect type in assignment for va + - remoteproc: stm32: Fix incorrect type assignment returned by + stm32_rproc_get_loaded_rsc_tablef + - iio: pressure: mprls0025pa fix off-by-one enum + - usb: phy: generic: Get the vbus supply + - tty: vt: fix 20 vs 0x20 typo in EScsiignore + - serial: max310x: fix syntax error in IRQ error message + - tty: serial: samsung: fix tx_empty() to return TIOCSER_TEMT + - arm64: dts: broadcom: bcmbca: bcm4908: drop invalid switch cells + - coresight: Fix issue where a source device's helpers aren't disabled + - coresight: etm4x: Set skip_power_up in etm4_init_arch_data function + - xhci: Add interrupt pending autoclear flag to each interrupter + - xhci: make isoc_bei_interval variable interrupter specific. + - xhci: remove unnecessary event_ring_deq parameter from xhci_handle_event() + - xhci: update event ring dequeue pointer position to controller correctly + - coccinelle: device_attr_show: Remove useless expression STR + - kconfig: fix infinite loop when expanding a macro at the end of file + - iio: gts-helper: Fix division loop + - bus: mhi: ep: check the correct variable in mhi_ep_register_controller() + - hwtracing: hisi_ptt: Move type check to the beginning of + hisi_ptt_pmu_event_init() + - rtc: mt6397: select IRQ_DOMAIN instead of depending on it + - rtc: max31335: fix interrupt status reg + - serial: 8250_exar: Don't remove GPIO device on suspend + - staging: greybus: fix get_channel_from_mode() failure path + - mei: vsc: Call wake_up() in the threaded IRQ handler + - mei: vsc: Don't use sleeping condition in wait_event_timeout() + - usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin + - char: xilinx_hwicap: Fix NULL vs IS_ERR() bug + - x86/hyperv: Use per cpu initial stack for vtl context + - ASoC: tlv320adc3xxx: Don't strip remove function when driver is builtin + - thermal/drivers/mediatek/lvts_thermal: Fix a memory leak in an error + handling path + - thermal/drivers/qoriq: Fix getting tmu range + - io_uring: don't save/restore iowait state + - spi: lpspi: Avoid potential use-after-free in probe() + - spi: Restore delays for non-GPIO chip select + - ASoC: rockchip: i2s-tdm: Fix inaccurate sampling rates + - nouveau: reset the bo resource bus info after an eviction + - tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge() + - rds: tcp: Fix use-after-free of net in reqsk_timer_handler(). + - octeontx2-af: Use matching wake_up API variant in CGX command interface + - s390/vtime: fix average steal time calculation + - net/sched: taprio: proper TCA_TAPRIO_TC_ENTRY_INDEX check + - devlink: Fix devlink parallel commands processing + - riscv: Only check online cpus for emulated accesses + - soc: fsl: dpio: fix kcalloc() argument order + - cpufreq: Fix per-policy boost behavior on SoCs using cpufreq_boost_set_sw() + - io_uring: Fix release of pinned pages when __io_uaddr_map fails + - tcp: Fix refcnt handling in __inet_hash_connect(). + - vmxnet3: Fix missing reserved tailroom + - hsr: Fix uninit-value access in hsr_get_node() + - net: txgbe: fix clk_name exceed MAX_DEV_ID limits + - spi: spi-mem: add statistics support to ->exec_op() calls + - spi: Fix error code checking in spi_mem_exec_op() + - nvme: fix reconnection fail due to reserved tag allocation + - drm/xe: Invalidate userptr VMA on page pin fault + - drm/xe: Skip VMAs pin when requesting signal to the last XE_EXEC + - net: mediatek: mtk_eth_soc: clear MAC_MCR_FORCE_LINK only when MAC is up + - net: ethernet: mtk_eth_soc: fix PPE hanging issue + - io_uring: fix poll_remove stalled req completion + - ASoC: SOF: amd: Move signed_fw_image to struct acp_quirk_entry + - ASoC: SOF: amd: Skip IRAM/DRAM size modification for Steam Deck OLED + - riscv: Fix compilation error with FAST_GUP and rv32 + - xen/evtchn: avoid WARN() when unbinding an event channel + - xen/events: increment refcnt only if event channel is refcounted + - packet: annotate data-races around ignore_outgoing + - xfrm: Allow UDP encapsulation only in offload modes + - net: veth: do not manipulate GRO when using XDP + - net: dsa: mt7530: prevent possible incorrect XTAL frequency selection + - spi: spi-imx: fix off-by-one in mx51 CPU mode burst length + - drm: Fix drm_fixp2int_round() making it add 0.5 + - virtio: uapi: Drop __packed attribute in linux/virtio_pci.h + - vdpa_sim: reset must not run + - vdpa/mlx5: Allow CVQ size changes + - virtio: packed: fix unmap leak for indirect desc table + - net: move dev->state into net_device_read_txrx group + - wireguard: receive: annotate data-race around receiving_counter.counter + - rds: introduce acquire/release ordering in acquire/release_in_xmit() + - hsr: Handle failures in module init + - ipv4: raw: Fix sending packets from raw sockets via IPsec tunnels + - nouveau/gsp: don't check devinit disable on GSP. + - ceph: stop copying to iter at EOF on sync reads + - net: phy: fix phy_read_poll_timeout argument type in genphy_loopback + - dm-integrity: fix a memory leak when rechecking the data + - net/bnx2x: Prevent access to a freed page in page_pool + - devlink: fix port new reply cmd type + - octeontx2: Detect the mbox up or down message via register + - octeontx2-pf: Wait till detach_resources msg is complete + - octeontx2-pf: Use default max_active works instead of one + - octeontx2-pf: Send UP messages to VF only when VF is up. + - octeontx2-af: Use separate handlers for interrupts + - drm/amdgpu: add MMHUB 3.3.1 support + - drm/amdgpu: fix mmhub client id out-of-bounds access + - drm/amdgpu: drop setting buffer funcs in sdma442 + - netfilter: nft_set_pipapo: release elements in clone only from destroy path + - netfilter: nf_tables: do not compare internal table flags on updates + - rcu: add a helper to report consolidated flavor QS + - net: report RCU QS on threaded NAPI repolling + - bpf: report RCU QS in cpumap kthread + - net: dsa: mt7530: fix link-local frames that ingress vlan filtering ports + - net: dsa: mt7530: fix handling of all link-local frames + - netfilter: nf_tables: Fix a memory leak in nf_tables_updchain + - spi: spi-mt65xx: Fix NULL pointer access in interrupt handler + - selftests: forwarding: Fix ping failure due to short timeout + - dm io: Support IO priority + - dm-integrity: align the outgoing bio in integrity_recheck + - x86/efistub: Clear decompressor BSS in native EFI entrypoint + - x86/efistub: Don't clear BSS twice in mixed mode + - printk: Adjust mapping for 32bit seq macros + - printk: Use prb_first_seq() as base for 32bit seq macros + - Linux 6.8.2 + - [Config] updateconfig following v6.8.2 import + + * Provide python perf module (LP: #2051560) + - [Packaging] enable perf python module + - [Packaging] provide a wrapper module for python-perf + + * To support AMD Adaptive Backlight Management (ABM) for power profiles daemon + >= 2.0 (LP: #2056716) + - drm/amd/display: add panel_power_savings sysfs entry to eDP connectors + - drm/amdgpu: respect the abmlevel module parameter value if it is set + + * Miscellaneous Ubuntu changes + - [Config] Disable StarFive JH7100 support + - [Config] Disable Renesas RZ/Five support + - [Config] Disable BINFMT_FLAT for riscv64 + + -- Roxana Nicolescu Wed, 01 May 2024 16:02:05 +0200 + +linux (6.8.0-31.31) noble; urgency=medium + + * noble/linux: 6.8.0-31.31 -proposed tracker (LP: #2062933) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/d2024.04.04) + + -- Andrea Righi Fri, 19 Apr 2024 23:46:38 +0200 + +linux (6.8.0-30.30) noble; urgency=medium + + * noble/linux: 6.8.0-30.30 -proposed tracker (LP: #2061893) + + * System unstable, kernel ring buffer flooded with "BUG: Bad page state in + process swapper/0" (LP: #2056706) + - xen-netfront: Add missing skb_mark_for_recycle + + -- Andrea Righi Tue, 16 Apr 2024 21:17:11 +0200 + +linux (6.8.0-29.29) noble; urgency=medium + + * noble/linux: 6.8.0-29.29 -proposed tracker (LP: #2061888) + + * [24.04 FEAT] [SEC2353] zcrypt: extend error recovery to deal with device + scans (LP: #2050019) + - s390/zcrypt: harmonize debug feature calls and defines + - s390/zcrypt: introduce dynamic debugging for AP and zcrypt code + - s390/pkey: harmonize pkey s390 debug feature calls + - s390/pkey: introduce dynamic debugging for pkey + - s390/ap: add debug possibility for AP messages + - s390/zcrypt: add debug possibility for CCA and EP11 messages + - s390/ap: rearm APQNs bindings complete completion + - s390/ap: clarify AP scan bus related functions and variables + - s390/ap: rework ap_scan_bus() to return true on config change + - s390/ap: introduce mutex to lock the AP bus scan + - s390/zcrypt: introduce retries on in-kernel send CPRB functions + - s390/zcrypt: improve zcrypt retry behavior + - s390/pkey: improve pkey retry behavior + + * [24.04 FEAT] Memory hotplug vmem pages (s390x) (LP: #2051835) + - mm/memory_hotplug: introduce MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers + - s390/mm: allocate vmemmap pages from self-contained memory range + - s390/sclp: remove unhandled memory notifier type + - s390/mm: implement MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers + - s390: enable MHP_MEMMAP_ON_MEMORY + - [Config] enable CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE and + CONFIG_MHP_MEMMAP_ON_MEMORY for s390x + + -- Paolo Pisati Tue, 16 Apr 2024 20:32:09 +0200 + +linux (6.8.0-28.28) noble; urgency=medium + + * noble/linux: 6.8.0-28.28 -proposed tracker (LP: #2061867) + + * linux-gcp 6.8.0-1005.5 (+ others) Noble kernel regression iwth new apparmor + profiles/features (LP: #2061851) + - SAUCE: apparmor4.0.0 [92/90]: fix address mapping for recvfrom + + -- Paolo Pisati Tue, 16 Apr 2024 18:29:17 +0200 + +linux (6.8.0-25.25) noble; urgency=medium + + * noble/linux: 6.8.0-25.25 -proposed tracker (LP: #2061083) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/d2024.04.04) + + * Apply mitigations for the native BHI hardware vulnerabilty (LP: #2060909) + - x86/cpufeatures: Add new word for scattered features + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/syscall: Don't force use of indirect calls for system calls + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - KVM: x86: Add BHI_NO + - x86: set SPECTRE_BHI_ON as default + - [Config] enable spectre_bhi=auto by default + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [01/90]: LSM stacking v39: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor4.0.0 [02/90]: LSM stacking v39: SM: Infrastructure + management of the sock security + - SAUCE: apparmor4.0.0 [03/90]: LSM stacking v39: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor4.0.0 [04/90]: LSM stacking v39: IMA: avoid label collisions + with stacked LSMs + - SAUCE: apparmor4.0.0 [05/90]: LSM stacking v39: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor4.0.0 [06/90]: LSM stacking v39: LSM: Add lsmblob_to_secctx + hook + - SAUCE: apparmor4.0.0 [07/90]: LSM stacking v39: Audit: maintain an lsmblob + in audit_context + - SAUCE: apparmor4.0.0 [08/90]: LSM stacking v39: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor4.0.0 [09/90]: LSM stacking v39: Audit: Update shutdown LSM + data + - SAUCE: apparmor4.0.0 [10/90]: LSM stacking v39: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor4.0.0 [11/90]: LSM stacking v39: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor4.0.0 [12/90]: LSM stacking v39: Audit: use an lsmblob in + audit_names + - SAUCE: apparmor4.0.0 [13/90]: LSM stacking v39: LSM: Create new + security_cred_getlsmblob LSM hook + - SAUCE: apparmor4.0.0 [14/90]: LSM stacking v39: Audit: Change context data + from secid to lsmblob + - SAUCE: apparmor4.0.0 [15/90]: LSM stacking v39: Netlabel: Use lsmblob for + audit data + - SAUCE: apparmor4.0.0 [16/90]: LSM stacking v39: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor4.0.0 [17/90]: LSM stacking v39: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [18/90]: LSM stacking v39: LSM: Use lsmcontext in + security_lsmblob_to_secctx + - SAUCE: apparmor4.0.0 [19/90]: LSM stacking v39: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor4.0.0 [20/90]: LSM stacking v39: LSM: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor4.0.0 [21/90]: LSM stacking v39: LSM: + security_lsmblob_to_secctx module selection + - SAUCE: apparmor4.0.0 [22/90]: LSM stacking v39: Audit: Create audit_stamp + structure + - SAUCE: apparmor4.0.0 [23/90]: LSM stacking v39: Audit: Allow multiple + records in an audit_buffer + - SAUCE: apparmor4.0.0 [24/90]: LSM stacking v39: Audit: Add record for + multiple task security contexts + - SAUCE: apparmor4.0.0 [25/90]: LSM stacking v39: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor4.0.0 [26/90]: LSM stacking v39: Audit: Add record for + multiple object contexts + - SAUCE: apparmor4.0.0 [27/90]: LSM stacking v39: LSM: Remove unused + lsmcontext_init() + - SAUCE: apparmor4.0.0 [28/90]: LSM stacking v39: LSM: Improve logic in + security_getprocattr + - SAUCE: apparmor4.0.0 [29/90]: LSM stacking v39: LSM: secctx provider check + on release + - SAUCE: apparmor4.0.0 [31/90]: LSM stacking v39: LSM: Exclusive secmark usage + - SAUCE: apparmor4.0.0 [32/90]: LSM stacking v39: LSM: Identify which LSM + handles the context string + - SAUCE: apparmor4.0.0 [33/90]: LSM stacking v39: AppArmor: Remove the + exclusive flag + - SAUCE: apparmor4.0.0 [34/90]: LSM stacking v39: LSM: Add mount opts blob + size tracking + - SAUCE: apparmor4.0.0 [35/90]: LSM stacking v39: LSM: allocate mnt_opts blobs + instead of module specific data + - SAUCE: apparmor4.0.0 [36/90]: LSM stacking v39: LSM: Infrastructure + management of the key security blob + - SAUCE: apparmor4.0.0 [37/90]: LSM stacking v39: LSM: Infrastructure + management of the mnt_opts security blob + - SAUCE: apparmor4.0.0 [38/90]: LSM stacking v39: LSM: Correct handling of + ENOSYS in inode_setxattr + - SAUCE: apparmor4.0.0 [39/90]: LSM stacking v39: LSM: Remove lsmblob + scaffolding + - SAUCE: apparmor4.0.0 [40/90]: LSM stacking v39: LSM: Allow reservation of + netlabel + - SAUCE: apparmor4.0.0 [41/90]: LSM stacking v39: LSM: restrict + security_cred_getsecid() to a single LSM + - SAUCE: apparmor4.0.0 [42/90]: LSM stacking v39: Smack: Remove + LSM_FLAG_EXCLUSIVE + - SAUCE: apparmor4.0.0 [43/90]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0 + [12/95]: add/use fns to print hash string hex value + - SAUCE: apparmor4.0.0 [44/90]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor4.0.0 [45/90]: add unpriviled user ns mediation + - SAUCE: apparmor4.0.0 [46/90]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor4.0.0 [47/90]: af_unix mediation + - SAUCE: apparmor4.0.0 [48/90]: Add fine grained mediation of posix mqueues + - SAUCE: apparmor4.0.0 [49/90]: setup slab cache for audit data + - SAUCE: apparmor4.0.0 [50/90]: Improve debug print infrastructure + - SAUCE: apparmor4.0.0 [51/90]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor4.0.0 [52/90]: enable userspace upcall for mediation + - SAUCE: apparmor4.0.0 [53/90]: prompt - lock down prompt interface + - SAUCE: apparmor4.0.0 [54/90]: prompt - allow controlling of caching of a + prompt response + - SAUCE: apparmor4.0.0 [55/90]: prompt - add refcount to audit_node in prep or + reuse and delete + - SAUCE: apparmor4.0.0 [56/90]: prompt - refactor to moving caching to + uresponse + - SAUCE: apparmor4.0.0 [57/90]: prompt - Improve debug statements + - SAUCE: apparmor4.0.0 [58/90]: prompt - fix caching + - SAUCE: apparmor4.0.0 [59/90]: prompt - rework build to use append fn, to + simplify adding strings + - SAUCE: apparmor4.0.0 [60/90]: prompt - refcount notifications + - SAUCE: apparmor4.0.0 [61/90]: prompt - add the ability to reply with a + profile name + - SAUCE: apparmor4.0.0 [62/90]: prompt - fix notification cache when updating + - SAUCE: apparmor4.0.0 [63/90]: prompt - add tailglob on name for cache + support + - SAUCE: apparmor4.0.0 [64/90]: prompt - allow profiles to set prompts as + interruptible + - SAUCE: apparmor4.0.0 [65/90] v6.8 prompt:fixup interruptible + - SAUCE: apparmor4.0.0 [69/90]: add io_uring mediation + - SAUCE: apparmor4.0.0 [70/90]: apparmor: fix oops when racing to retrieve + notification + - SAUCE: apparmor4.0.0 [71/90]: apparmor: fix notification header size + - SAUCE: apparmor4.0.0 [72/90]: apparmor: fix request field from a prompt + reply that denies all access + - SAUCE: apparmor4.0.0 [73/90]: apparmor: open userns related sysctl so lxc + can check if restriction are in place + - SAUCE: apparmor4.0.0 [74/90]: apparmor: cleanup attachment perm lookup to + use lookup_perms() + - SAUCE: apparmor4.0.0 [75/90]: apparmor: remove redundant unconfined check. + - SAUCE: apparmor4.0.0 [76/90]: apparmor: switch signal mediation to using + RULE_MEDIATES + - SAUCE: apparmor4.0.0 [77/90]: apparmor: ensure labels with more than one + entry have correct flags + - SAUCE: apparmor4.0.0 [78/90]: apparmor: remove explicit restriction that + unconfined cannot use change_hat + - SAUCE: apparmor4.0.0 [79/90]: apparmor: cleanup: refactor file_perm() to + provide semantics of some checks + - SAUCE: apparmor4.0.0 [80/90]: apparmor: carry mediation check on label + - SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy uses of unconfined() to + label_mediates() + - SAUCE: apparmor4.0.0 [82/90]: apparmor: add additional flags to extended + permission. + - SAUCE: apparmor4.0.0 [83/90]: apparmor: add support for profiles to define + the kill signal + - SAUCE: apparmor4.0.0 [84/90]: apparmor: fix x_table_lookup when stacking is + not the first entry + - SAUCE: apparmor4.0.0 [85/90]: apparmor: allow profile to be transitioned + when a user ns is created + - SAUCE: apparmor4.0.0 [86/90]: apparmor: add ability to mediate caps with + policy state machine + - SAUCE: apparmor4.0.0 [87/90]: fixup notify + - SAUCE: apparmor4.0.0 [88/90]: apparmor: add fine grained ipv4/ipv6 mediation + - SAUCE: apparmor4.0.0 [89/90]:apparmor: disable tailglob responses for now + - SAUCE: apparmor4.0.0 [90/90]: apparmor: Fix notify build warnings + - SAUCE: apparmor4.0.0: fix reserved mem for when we save ipv6 addresses + - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe] + apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic + (LP: #2032602) + - SAUCE: apparmor4.0.0 [66/90]: prompt - add support for advanced filtering of + notifications + - SAUCE: apparmor4.0.0 [67/90]: userns - add the ability to reference a global + variable for a feature value + - SAUCE: apparmor4.0.0 [68/90]: userns - make it so special unconfined + profiles can mediate user namespaces + + * [MTL] x86: Fix Cache info sysfs is not populated (LP: #2049793) + - SAUCE: cacheinfo: Check for null last-level cache info + - SAUCE: cacheinfo: Allocate memory for memory if not done from the primary + CPU + - SAUCE: x86/cacheinfo: Delete global num_cache_leaves + - SAUCE: x86/cacheinfo: Clean out init_cache_level() + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with + CONFIG_SECURITY=n + - [Config] toolchain version update + + -- Paolo Pisati Fri, 12 Apr 2024 10:42:33 +0200 + +linux (6.8.0-22.22) noble; urgency=medium + + * noble/linux: 6.8.0-22.22 -proposed tracker (LP: #2060238) + + -- Andrea Righi Thu, 04 Apr 2024 23:00:49 +0200 + +linux (6.8.0-21.21) noble; urgency=medium + + * noble/linux: 6.8.0-21.21 -proposed tracker (LP: #2060225) + + * Miscellaneous Ubuntu changes + - [Config] update toolchain version in annotations + + -- Andrea Righi Thu, 04 Apr 2024 22:20:27 +0200 + +linux (6.8.0-20.20) noble; urgency=medium + + * noble/linux: 6.8.0-20.20 -proposed tracker (LP: #2058221) + + * Noble update: v6.8.1 upstream stable release (LP: #2058224) + - x86/mmio: Disable KVM mitigation when X86_FEATURE_CLEAR_CPU_BUF is set + - Documentation/hw-vuln: Add documentation for RFDS + - x86/rfds: Mitigate Register File Data Sampling (RFDS) + - KVM/x86: Export RFDS_NO and RFDS_CLEAR to guests + - Linux 6.8.1 + + * Autopkgtest failures on amd64 (LP: #2048768) + - [Packaging] update to clang-18 + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with + CONFIG_SECURITY=n + - [Config] amd64: MITIGATION_RFDS=y + + -- Paolo Pisati Mon, 18 Mar 2024 11:08:14 +0100 + +linux (6.8.0-19.19) noble; urgency=medium + + * noble/linux: 6.8.0-19.19 -proposed tracker (LP: #2057910) + + * Miscellaneous Ubuntu changes + - [Packaging] re-introduce linux-doc as an empty package + + -- Paolo Pisati Thu, 14 Mar 2024 14:36:14 +0100 + +linux (6.8.0-18.18) noble; urgency=medium + + * noble/linux: 6.8.0-18.18 -proposed tracker (LP: #2057456) + + * Miscellaneous Ubuntu changes + - [Packaging] drop dependency on libclang-17 + + -- Paolo Pisati Tue, 12 Mar 2024 14:44:13 +0100 + +linux (6.8.0-17.17) noble; urgency=medium + + * noble/linux: 6.8.0-17.17 -proposed tracker (LP: #2056745) + + * Miscellaneous upstream changes + - Revert "UBUNTU: [Packaging] Add debian/control sanity check" + + -- Paolo Pisati Mon, 11 Mar 2024 12:46:38 +0100 + +linux (6.8.0-16.16) noble; urgency=medium + + * noble/linux: 6.8.0-16.16 -proposed tracker (LP: #2056738) + + * left-over ceph debugging printks (LP: #2056616) + - Revert "UBUNTU: SAUCE: ceph: make sure all the files successfully put before + unmounting" + + * qat: Improve error recovery flows (LP: #2056354) + - crypto: qat - add heartbeat error simulator + - crypto: qat - disable arbitration before reset + - crypto: qat - update PFVF protocol for recovery + - crypto: qat - re-enable sriov after pf reset + - crypto: qat - add fatal error notification + - crypto: qat - add auto reset on error + - crypto: qat - limit heartbeat notifications + - crypto: qat - improve aer error reset handling + - crypto: qat - change SLAs cleanup flow at shutdown + - crypto: qat - resolve race condition during AER recovery + - Documentation: qat: fix auto_reset section + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure + management of the sock security + - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions + with stacked LSMs + - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx + hook + - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob + in audit_context + - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM + data + - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in + audit_names + - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new + security_cred_getlsmblob LSM hook + - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data + from secid to lsmblob + - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for + audit data + - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in + security_lsmblob_to_secctx + - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM: + security_lsmblob_to_secctx module selection + - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp + structure + - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple + records in an audit_buffer + - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for + multiple task security contexts + - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for + multiple object contexts + - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused + lsmcontext_init() + - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in + security_getprocattr + - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check + on release + - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage + - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM + handles the context string + - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the + exclusive flag + - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob + size tracking + - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs + instead of module specific data + - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure + management of the key security blob + - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure + management of the mnt_opts security blob + - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of + ENOSYS in inode_setxattr + - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob + scaffolding + - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of + netlabel + - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict + security_cred_getsecid() to a single LSM + - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove + LSM_FLAG_EXCLUSIVE + - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0 + [12/95]: add/use fns to print hash string hex value + - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation + - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation + - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues + - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data + - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure + - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation + - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface + - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a + prompt response + - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or + reuse and delete + - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to + uresponse + - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements + - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching + - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to + simplify adding strings + - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications + - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a + profile name + - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating + - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache + support + - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as + interruptible + - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible + - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation + - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve + notification + - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size + - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt + reply that denies all access + - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc + can check if restriction are in place + - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to + use lookup_perms() + - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check. + - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using + RULE_MEDIATES + - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one + entry have correct flags + - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that + unconfined cannot use change_hat + - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to + provide semantics of some checks + - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label + - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to + label_mediates() + - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended + permission. + - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define + the kill signal + - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is + not the first entry + - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned + when a user ns is created + - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with + policy state machine + - SAUCE: apparmor4.0.0 [87/87]: fixup notify + - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe] + apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic + (LP: #2032602) + - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of + notifications + - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global + variable for a feature value + - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined + profiles can mediate user namespaces + + * Enable lowlatency settings in the generic kernel (LP: #2051342) + - [Config] enable low-latency settings + + * hwmon: (coretemp) Fix core count limitation (LP: #2056126) + - hwmon: (coretemp) Introduce enum for attr index + - hwmon: (coretemp) Remove unnecessary dependency of array index + - hwmon: (coretemp) Replace sensor_device_attribute with device_attribute + - hwmon: (coretemp) Remove redundant pdata->cpu_map[] + - hwmon: (coretemp) Abstract core_temp helpers + - hwmon: (coretemp) Split package temp_data and core temp_data + - hwmon: (coretemp) Remove redundant temp_data->is_pkg_data + - hwmon: (coretemp) Use dynamic allocated memory for core temp_data + + * Miscellaneous Ubuntu changes + - [Config] Disable CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION + - [Packaging] remove debian/scripts/misc/arch-has-odm-enabled.sh + - rebase on v6.8 + - [Config] toolchain version update + + * Miscellaneous upstream changes + - crypto: qat - add fatal error notify method + + * Rebase on v6.8 + + -- Paolo Pisati Mon, 11 Mar 2024 10:14:10 +0100 + +linux (6.8.0-15.15) noble; urgency=medium + + * noble/linux: 6.8.0-15.15 -proposed tracker (LP: #2055871) + + * Miscellaneous Ubuntu changes + - rebase on v6.8-rc7 + + * Miscellaneous upstream changes + - Revert "UBUNTU: [Packaging] Transition laptop-23.10 to generic" + + * Rebase on v6.8-rc7 + + -- Paolo Pisati Mon, 04 Mar 2024 11:50:51 +0100 + +linux (6.8.0-14.14) noble; urgency=medium + + * noble/linux: 6.8.0-14.14 -proposed tracker (LP: #2055551) + + * Please change CONFIG_CONSOLE_LOGLEVEL_QUIET to 3 (LP: #2049390) + - [Config] reduce verbosity when booting in quiet mode + + * linux: please move erofs.ko (CONFIG_EROFS for EROFS support) from linux- + modules-extra to linux-modules (LP: #2054809) + - UBUNTU [Packaging]: Include erofs in linux-modules instead of linux-modules- + extra + + * linux: please move dmi-sysfs.ko (CONFIG_DMI_SYSFS for SMBIOS support) from + linux-modules-extra to linux-modules (LP: #2045561) + - [Packaging] Move dmi-sysfs.ko into linux-modules + + * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and + CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440) + - [Config] enable Intel DMA remapping by default + + * disable Intel DMA remapping by default (LP: #1971699) + - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON + + * Packaging resync (LP: #1786013) + - debian.master/dkms-versions -- update from kernel-versions + (main/d2024.02.29) + + * Miscellaneous Ubuntu changes + - SAUCE: modpost: Replace 0-length array with flex-array member + - [packaging] do not include debian/ directory in a binary package + - [packaging] remove debian/stamps/keep-dir + + -- Paolo Pisati Fri, 01 Mar 2024 11:45:12 +0100 + +linux (6.8.0-13.13) noble; urgency=medium + + * noble/linux: 6.8.0-13.13 -proposed tracker (LP: #2055421) + + * Packaging resync (LP: #1786013) + - debian.master/dkms-versions -- update from kernel-versions + (main/d2024.02.29) + + * Miscellaneous Ubuntu changes + - rebase on v6.8-rc6 + - [Config] updateconfifs following v6.8-rc6 rebase + + * Rebase on v6.8-rc6 + + -- Paolo Pisati Thu, 29 Feb 2024 15:02:24 +0100 + +linux (6.8.0-12.12) noble; urgency=medium + + * linux-tools-common: man page of usbip[d] is misplaced (LP: #2054094) + - [Packaging] rules: Put usbip manpages in the correct directory + + * Validate connection interval to pass Bluetooth Test Suite (LP: #2052005) + - Bluetooth: Enforce validation on max value of connection interval + + * Turning COMPAT_32BIT_TIME off on s390x (LP: #2038583) + - [Config] Turn off 31-bit COMPAT on s390x + + * Don't produce linux-source binary package (LP: #2043994) + - [Packaging] Add debian/control sanity check + + * Don't produce linux-*-source- package (LP: #2052439) + - [Packaging] Move linux-source package stub to debian/control.d + - [Packaging] Build linux-source package only for the main kernel + + * Don't produce linux-*-cloud-tools-common, linux-*-tools-common and + linux-*-tools-host binary packages (LP: #2048183) + - [Packaging] Move indep tools package stubs to debian/control.d + - [Packaging] Build indep tools packages only for the main kernel + + * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and + CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440) + - [Config] enable Intel DMA remapping by default + + * disable Intel DMA remapping by default (LP: #1971699) + - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON + + * Miscellaneous Ubuntu changes + - [Packaging] Transition laptop-23.10 to generic + + -- Paolo Pisati Thu, 22 Feb 2024 14:31:00 +0100 + +linux (6.8.0-11.11) noble; urgency=medium + + * noble/linux: 6.8.0-11.11 -proposed tracker (LP: #2053094) + + * Miscellaneous Ubuntu changes + - [Packaging] riscv64: disable building unnecessary binary debs + + -- Paolo Pisati Wed, 14 Feb 2024 00:04:31 +0100 + +linux (6.8.0-10.10) noble; urgency=medium + + * noble/linux: 6.8.0-10.10 -proposed tracker (LP: #2053015) + + * Miscellaneous Ubuntu changes + - [Packaging] add Rust build-deps for riscv64 + + * Miscellaneous upstream changes + - Revert "Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on + riscv64"" + + -- Paolo Pisati Tue, 13 Feb 2024 13:23:47 +0100 + +linux (6.8.0-9.9) noble; urgency=medium + + * noble/linux: 6.8.0-9.9 -proposed tracker (LP: #2052945) + + * Miscellaneous upstream changes + - Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on + riscv64" + + -- Paolo Pisati Mon, 12 Feb 2024 15:49:20 +0100 + +linux (6.8.0-8.8) noble; urgency=medium + + * noble/linux: 6.8.0-8.8 -proposed tracker (LP: #2052918) + + * Miscellaneous Ubuntu changes + - [Packaging] riscv64: enable linux-libc-dev build + - v6.8-rc4 rebase + + * Rebase on v6.8-rc4 + + -- Paolo Pisati Mon, 12 Feb 2024 10:13:34 +0100 + +linux (6.8.0-7.7) noble; urgency=medium + + * noble/linux: 6.8.0-7.7 -proposed tracker (LP: #2052691) + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure + management of the sock security + - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions + with stacked LSMs + - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx + hook + - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob + in audit_context + - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM + data + - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in + audit_names + - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new + security_cred_getlsmblob LSM hook + - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data + from secid to lsmblob + - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for + audit data + - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in + security_lsmblob_to_secctx + - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM: + security_lsmblob_to_secctx module selection + - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp + structure + - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple + records in an audit_buffer + - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for + multiple task security contexts + - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for + multiple object contexts + - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused + lsmcontext_init() + - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in + security_getprocattr + - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check + on release + - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage + - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM + handles the context string + - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the + exclusive flag + - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob + size tracking + - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs + instead of module specific data + - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure + management of the key security blob + - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure + management of the mnt_opts security blob + - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of + ENOSYS in inode_setxattr + - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob + scaffolding + - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of + netlabel + - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict + security_cred_getsecid() to a single LSM + - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove + LSM_FLAG_EXCLUSIVE + - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0 + [12/95]: add/use fns to print hash string hex value + - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation + - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation + - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues + - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data + - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure + - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation + - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface + - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a + prompt response + - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or + reuse and delete + - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to + uresponse + - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements + - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching + - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to + simplify adding strings + - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications + - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a + profile name + - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating + - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache + support + - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as + interruptible + - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible + - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation + - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve + notification + - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size + - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt + reply that denies all access + - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc + can check if restriction are in place + - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to + use lookup_perms() + - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check. + - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using + RULE_MEDIATES + - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one + entry have correct flags + - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that + unconfined cannot use change_hat + - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to + provide semantics of some checks + - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label + - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to + label_mediates() + - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended + permission. + - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define + the kill signal + - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is + not the first entry + - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned + when a user ns is created + - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with + policy state machine + - SAUCE: apparmor4.0.0 [87/87]: fixup notify + - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe] + apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic + (LP: #2032602) + - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of + notifications + - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global + variable for a feature value + - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined + profiles can mediate user namespaces + + -- Paolo Pisati Thu, 08 Feb 2024 12:05:44 +0100 + +linux (6.8.0-6.6) noble; urgency=medium + + * noble/linux: 6.8.0-6.6 -proposed tracker (LP: #2052592) + + * Packaging resync (LP: #1786013) + - debian.master/dkms-versions -- update from kernel-versions + (main/d2024.02.07) + - [Packaging] update variants + + * FIPS kernels should default to fips mode (LP: #2049082) + - SAUCE: Enable fips mode by default, in FIPS kernels only + + * Fix snapcraftyaml.yaml for jammy:linux-raspi (LP: #2051468) + - [Packaging] Remove old snapcraft.yaml + + * Azure: Fix regression introduced in LP: #2045069 (LP: #2052453) + - hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed + + * Miscellaneous Ubuntu changes + - [Packaging] Remove in-tree abi checks + - [Packaging] drop abi files with clean + - [Packaging] Remove do_full_source variable (fixup) + - [Packaging] Remove update-dkms-versions and move dkms-versions + - [Config] updateconfigs following v6.8-rc3 rebase + - [packaging] rename to linux + - [packaging] rebase on v6.8-rc3 + - [packaging] disable signing for ppc64el + + * Rebase on v6.8-rc3 + + -- Paolo Pisati Wed, 07 Feb 2024 15:13:52 +0100 + +linux (6.8.0-5.5) noble; urgency=medium + + * noble/linux-unstable: 6.8.0-5.5 -proposed tracker (LP: #2052136) + + * Miscellaneous upstream changes + - Revert "mm/sparsemem: fix race in accessing memory_section->usage" + + -- Paolo Pisati Fri, 02 Feb 2024 12:59:09 +0100 + +linux-unstable (6.8.0-4.4) noble; urgency=medium + + * noble/linux-unstable: 6.8.0-4.4 -proposed tracker (LP: #2051502) + + * Migrate from fbdev drivers to simpledrm and DRM fbdev emulation layer + (LP: #1965303) + - [Config] enable simpledrm and DRM fbdev emulation layer + + * Miscellaneous Ubuntu changes + - [Config] toolchain update + + * Miscellaneous upstream changes + - rust: upgrade to Rust 1.75.0 + + -- Paolo Pisati Mon, 29 Jan 2024 14:49:49 +0100 + +linux-unstable (6.8.0-3.3) noble; urgency=medium + + * noble/linux-unstable: 6.8.0-3.3 -proposed tracker (LP: #2051488) + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0 + [12/95]: add/use fns to print hash string hex value + - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation + - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation + - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues + - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data + - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure + - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation + - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface + - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a + prompt response + - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or + reuse and delete + - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to + uresponse + - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements + - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching + - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to + simplify adding strings + - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications + - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a + profile name + - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating + - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache + support + - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as + interruptible + - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation + - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * apparmor restricts read access of user namespace mediation sysctls to root + (LP: #2040194) + - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc + can check if restriction are in place + + * AppArmor spams kernel log with assert when auditing (LP: #2040192) + - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt + reply that denies all access + + * apparmor notification files verification (LP: #2040250) + - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size + + * apparmor oops when racing to retrieve a notification (LP: #2040245) + - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve + notification + + * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe] + apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic + (LP: #2032602) + - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of + notifications + - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global + variable for a feature value + - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined + profiles can mediate user namespaces + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure + management of the sock security + - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions + with stacked LSMs + - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx + hook + - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob + in audit_context + - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM + data + - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in + audit_names + - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new + security_cred_getlsmblob LSM hook + - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data + from secid to lsmblob + - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for + audit data + - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in + security_lsmblob_to_secctx + - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM: + security_lsmblob_to_secctx module selection + - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp + structure + - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple + records in an audit_buffer + - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for + multiple task security contexts + - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for + multiple object contexts + - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused + lsmcontext_init() + - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in + security_getprocattr + - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check + on release + - SAUCE: apparmor4.0.0 [30/87]: LSM stacking v39: LSM: Single calls in + socket_getpeersec hooks + - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage + - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM + handles the context string + - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the + exclusive flag + - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob + size tracking + - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs + instead of module specific data + - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure + management of the key security blob + - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure + management of the mnt_opts security blob + - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of + ENOSYS in inode_setxattr + - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob + scaffolding + - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of + netlabel + - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict + security_cred_getsecid() to a single LSM + - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove + LSM_FLAG_EXCLUSIVE + - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible + - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to + use lookup_perms() + - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check. + - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using + RULE_MEDIATES + - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one + entry have correct flags + - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that + unconfined cannot use change_hat + - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to + provide semantics of some checks + - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label + - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to + label_mediates() + - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended + permission. + - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define + the kill signal + - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is + not the first entry + - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned + when a user ns is created + - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with + policy state machine + - SAUCE: apparmor4.0.0 [87/87]: fixup notify + - [Config] updateconfigs following v6.8-rc2 rebase + + -- Paolo Pisati Mon, 29 Jan 2024 08:59:32 +0100 + +linux-unstable (6.8.0-2.2) noble; urgency=medium + + * noble/linux-unstable: 6.8.0-2.2 -proposed tracker (LP: #2051110) + + * Miscellaneous Ubuntu changes + - [Config] toolchain update + - [Config] enable Rust + + -- Paolo Pisati Wed, 24 Jan 2024 13:10:07 +0100 + +linux-unstable (6.8.0-1.1) noble; urgency=medium + + * noble/linux-unstable: 6.8.0-1.1 -proposed tracker (LP: #2051102) + + * Miscellaneous Ubuntu changes + - [packaging] move to v6.8-rc1 + - [Config] updateconfigs following v6.8-rc1 rebase + - SAUCE: export file_close_fd() instead of close_fd_get_file() + - SAUCE: cpufreq: s/strlcpy/strscpy/ + - debian/dkms-versions -- temporarily disable zfs dkms + - debian/dkms-versions -- temporarily disable ipu6 and isvsc dkms + - debian/dkms-versions -- temporarily disable v4l2loopback + + -- Paolo Pisati Wed, 24 Jan 2024 10:48:37 +0100 + +linux-unstable (6.8.0-0.0) noble; urgency=medium + + * Empty entry. + + -- Paolo Pisati Tue, 23 Jan 2024 11:36:40 +0100 + +linux-unstable (6.7.0-7.7) noble; urgency=medium + + * noble/linux-unstable: 6.7.0-7.7 -proposed tracker (LP: #2049357) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + + * Miscellaneous Ubuntu changes + - [Packaging] re-enable signing for s390x and ppc64el + + -- Andrea Righi Mon, 15 Jan 2024 08:41:11 +0100 + +linux-unstable (6.7.0-6.6) noble; urgency=medium + + * Empty entry. + + -- Andrea Righi Mon, 15 Jan 2024 08:30:50 +0100 + +linux (6.7.0-2.2) noble; urgency=medium + + * noble/linux: 6.7.0-2.2 -proposed tracker (LP: #2049182) + + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + * Enforce RETPOLINE and SLS mitigrations (LP: #2046440) + - SAUCE: objtool: Make objtool check actually fatal upon fatal errors + - SAUCE: objtool: make objtool SLS validation fatal when building with + CONFIG_SLS=y + - SAUCE: objtool: make objtool RETPOLINE validation fatal when building with + CONFIG_RETPOLINE=y + - SAUCE: scripts: remove generating .o-ur objects + - [Packaging] Remove all custom retpoline-extract code + - Revert "UBUNTU: SAUCE: vga_set_mode -- avoid jump tables" + - Revert "UBUNTU: SAUCE: early/late -- annotate indirect calls in early/late + initialisation code" + - Revert "UBUNTU: SAUCE: apm -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end}" + + * Miscellaneous Ubuntu changes + - [Packaging] temporarily disable riscv64 builds + - [Packaging] temporarily disable Rust dependencies on riscv64 + + -- Andrea Righi Fri, 12 Jan 2024 09:21:57 +0100 + +linux (6.7.0-1.1) noble; urgency=medium + + * noble/linux: 6.7.0-1.1 -proposed tracker (LP: #2048859) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - debian/dkms-versions -- update from kernel-versions (main/d2024.01.02) + + * [UBUNTU 23.04] Regression: Ubuntu 23.04/23.10 do not include uvdevice + anymore (LP: #2048919) + - [Config] Enable S390_UV_UAPI (built-in) + + * Support mipi camera on Intel Meteor Lake platform (LP: #2031412) + - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs on Meteor + Lake + - SAUCE: platform/x86: int3472: Add handshake GPIO function + + * [SRU][J/L/M] UBUNTU: [Packaging] Make WWAN driver a loadable module + (LP: #2033406) + - [Packaging] Make WWAN driver loadable modules + + * usbip: error: failed to open /usr/share/hwdata//usb.ids (LP: #2039439) + - [Packaging] Make linux-tools-common depend on hwdata + + * [Mediatek] mt8195-demo: enable CONFIG_MTK_IOMMU as module for multimedia and + PCIE peripherals (LP: #2036587) + - [Config] Enable CONFIG_MTK_IOMMU on arm64 + + * linux-*: please enable dm-verity kconfigs to allow MoK/db verified root + images (LP: #2019040) + - [Config] CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING=y + + * kexec enable to load/kdump zstd compressed zimg (LP: #2037398) + - [Packaging] Revert arm64 image format to Image.gz + + * Mantic minimized/minimal cloud images do not receive IP address during + provisioning; systemd regression with wait-online (LP: #2036968) + - [Config] Enable virtio-net as built-in to avoid race + + * Make backlight module auto detect dell_uart_backlight (LP: #2008882) + - SAUCE: ACPI: video: Dell AIO UART backlight detection + + * Linux 6.2 fails to reboot with current u-boot-nezha (LP: #2021364) + - [Config] Default to performance CPUFreq governor on riscv64 + + * Enable Nezha board (LP: #1975592) + - [Config] Build in D1 clock drivers on riscv64 + - [Config] Enable CONFIG_SUN6I_RTC_CCU on riscv64 + - [Config] Enable CONFIG_SUNXI_WATCHDOG on riscv64 + - [Config] Disable SUN50I_DE2_BUS on riscv64 + - [Config] Disable unneeded sunxi pinctrl drivers on riscv64 + + * Enable StarFive VisionFive 2 board (LP: #2013232) + - [Config] Enable CONFIG_PINCTRL_STARFIVE_JH7110_SYS on riscv64 + - [Config] Enable CONFIG_STARFIVE_WATCHDOG on riscv64 + + * rcu_sched detected stalls on CPUs/tasks (LP: #1967130) + - [Config] Enable virtually mapped stacks on riscv64 + + * Check for changes relevant for security certifications (LP: #1945989) + - [Packaging] Add a new fips-checks script + + * Installation support for SMARC RZ/G2L platform (LP: #2030525) + - [Config] build Renesas RZ/G2L USBPHY control driver statically + + * Add support for kernels compiled with CONFIG_EFI_ZBOOT (LP: #2002226) + - [Config]: Turn on CONFIG_EFI_ZBOOT on ARM64 + + * Default module signing algo should be accelerated (LP: #2034061) + - [Config] Default module signing algo should be accelerated + + * Miscellaneous Ubuntu changes + - [Config] annotations clean-up + + [ Upstream Kernel Changes ] + + * Rebase to v6.7 + + -- Andrea Righi Thu, 11 Jan 2024 11:49:07 +0100 + +linux (6.7.0-0.0) noble; urgency=medium + + * Empty entry + + -- Andrea Righi Tue, 09 Jan 2024 09:27:23 +0100 + +linux-unstable (6.7.0-5.5) noble; urgency=medium + + * noble/linux-unstable: 6.7.0-5.5 -proposed tracker (LP: #2048118) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/d2024.01.02) + + * Miscellaneous Ubuntu changes + - [Packaging] re-enable Rust support + - [Packaging] temporarily disable riscv64 builds + + -- Andrea Righi Fri, 05 Jan 2024 12:33:10 +0100 + +linux-unstable (6.7.0-4.4) noble; urgency=medium + + * noble/linux-unstable: 6.7.0-4.4 -proposed tracker (LP: #2047807) + + * unconfined profile denies userns_create for chromium based processes + (LP: #1990064) + - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * apparmor restricts read access of user namespace mediation sysctls to root + (LP: #2040194) + - SAUCE: apparmor4.0.0 [69/69]: apparmor: open userns related sysctl so lxc + can check if restriction are in place + + * AppArmor spams kernel log with assert when auditing (LP: #2040192) + - SAUCE: apparmor4.0.0 [68/69]: apparmor: fix request field from a prompt + reply that denies all access + + * apparmor notification files verification (LP: #2040250) + - SAUCE: apparmor4.0.0 [67/69]: apparmor: fix notification header size + + * apparmor oops when racing to retrieve a notification (LP: #2040245) + - SAUCE: apparmor4.0.0 [66/69]: apparmor: fix oops when racing to retrieve + notification + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [01/69]: add/use fns to print hash string hex value + - SAUCE: apparmor4.0.0 [02/69]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor4.0.0 [03/69]: add unpriviled user ns mediation + - SAUCE: apparmor4.0.0 [04/69]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor4.0.0 [05/69]: af_unix mediation + - SAUCE: apparmor4.0.0 [06/69]: Add fine grained mediation of posix mqueues + - SAUCE: apparmor4.0.0 [07/69]: Stacking v38: LSM: Identify modules by more + than name + - SAUCE: apparmor4.0.0 [08/69]: Stacking v38: LSM: Add an LSM identifier for + external use + - SAUCE: apparmor4.0.0 [09/69]: Stacking v38: LSM: Identify the process + attributes for each module + - SAUCE: apparmor4.0.0 [10/69]: Stacking v38: LSM: Maintain a table of LSM + attribute data + - SAUCE: apparmor4.0.0 [11/69]: Stacking v38: proc: Use lsmids instead of lsm + names for attrs + - SAUCE: apparmor4.0.0 [12/69]: Stacking v38: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor4.0.0 [13/69]: Stacking v38: LSM: Infrastructure management + of the sock security + - SAUCE: apparmor4.0.0 [14/69]: Stacking v38: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor4.0.0 [15/69]: Stacking v38: LSM: provide lsm name and id + slot mappings + - SAUCE: apparmor4.0.0 [16/69]: Stacking v38: IMA: avoid label collisions with + stacked LSMs + - SAUCE: apparmor4.0.0 [17/69]: Stacking v38: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor4.0.0 [18/69]: Stacking v38: LSM: Use lsmblob in + security_kernel_act_as + - SAUCE: apparmor4.0.0 [19/69]: Stacking v38: LSM: Use lsmblob in + security_secctx_to_secid + - SAUCE: apparmor4.0.0 [20/69]: Stacking v38: LSM: Use lsmblob in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [21/69]: Stacking v38: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor4.0.0 [22/69]: Stacking v38: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor4.0.0 [23/69]: Stacking v38: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor4.0.0 [24/69]: Stacking v38: LSM: Use lsmblob in + security_cred_getsecid + - SAUCE: apparmor4.0.0 [25/69]: Stacking v38: LSM: Specify which LSM to + display + - SAUCE: apparmor4.0.0 [27/69]: Stacking v38: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor4.0.0 [28/69]: Stacking v38: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [29/69]: Stacking v38: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor4.0.0 [30/69]: Stacking v38: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor4.0.0 [31/69]: Stacking v38: LSM: security_secid_to_secctx in + netlink netfilter + - SAUCE: apparmor4.0.0 [32/69]: Stacking v38: NET: Store LSM netlabel data in + a lsmblob + - SAUCE: apparmor4.0.0 [33/69]: Stacking v38: binder: Pass LSM identifier for + confirmation + - SAUCE: apparmor4.0.0 [34/69]: Stacking v38: LSM: security_secid_to_secctx + module selection + - SAUCE: apparmor4.0.0 [35/69]: Stacking v38: Audit: Keep multiple LSM data in + audit_names + - SAUCE: apparmor4.0.0 [36/69]: Stacking v38: Audit: Create audit_stamp + structure + - SAUCE: apparmor4.0.0 [37/69]: Stacking v38: LSM: Add a function to report + multiple LSMs + - SAUCE: apparmor4.0.0 [38/69]: Stacking v38: Audit: Allow multiple records in + an audit_buffer + - SAUCE: apparmor4.0.0 [39/69]: Stacking v38: Audit: Add record for multiple + task security contexts + - SAUCE: apparmor4.0.0 [40/69]: Stacking v38: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor4.0.0 [41/69]: Stacking v38: Audit: Add record for multiple + object contexts + - SAUCE: apparmor4.0.0 [42/69]: Stacking v38: netlabel: Use a struct lsmblob + in audit data + - SAUCE: apparmor4.0.0 [43/69]: Stacking v38: LSM: Removed scaffolding + function lsmcontext_init + - SAUCE: apparmor4.0.0 [44/69]: Stacking v38: AppArmor: Remove the exclusive + flag + - SAUCE: apparmor4.0.0 [45/69]: setup slab cache for audit data + - SAUCE: apparmor4.0.0 [46/69]: Improve debug print infrastructure + - SAUCE: apparmor4.0.0 [47/69]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor4.0.0 [48/69]: enable userspace upcall for mediation + - SAUCE: apparmor4.0.0 [49/69]: prompt - lock down prompt interface + - SAUCE: apparmor4.0.0 [50/69]: prompt - allow controlling of caching of a + prompt response + - SAUCE: apparmor4.0.0 [51/69]: prompt - add refcount to audit_node in prep or + reuse and delete + - SAUCE: apparmor4.0.0 [52/69]: prompt - refactor to moving caching to + uresponse + - SAUCE: apparmor4.0.0 [53/69]: prompt - Improve debug statements + - SAUCE: apparmor4.0.0 [54/69]: prompt - fix caching + - SAUCE: apparmor4.0.0 [55/69]: prompt - rework build to use append fn, to + simplify adding strings + - SAUCE: apparmor4.0.0 [56/69]: prompt - refcount notifications + - SAUCE: apparmor4.0.0 [57/69]: prompt - add the ability to reply with a + profile name + - SAUCE: apparmor4.0.0 [58/69]: prompt - fix notification cache when updating + - SAUCE: apparmor4.0.0 [59/69]: prompt - add tailglob on name for cache + support + - SAUCE: apparmor4.0.0 [60/69]: prompt - allow profiles to set prompts as + interruptible + - SAUCE: apparmor4.0.0 [64/69]: advertise disconnected.path is available + - SAUCE: apparmor4.0.0 [65/69]: add io_uring mediation + + * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe] + apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic + (LP: #2032602) + - SAUCE: apparmor4.0.0 [61/69]: prompt - add support for advanced filtering of + notifications + - SAUCE: apparmor4.0.0 [62/69]: userns - add the ability to reference a global + variable for a feature value + - SAUCE: apparmor4.0.0 [63/69]: userns - make it so special unconfined + profiles can mediate user namespaces + + * udev fails to make prctl() syscall with apparmor=0 (as used by maas by + default) (LP: #2016908) // update apparmor and LSM stacking patch set + (LP: #2028253) + - SAUCE: apparmor4.0.0 [26/69]: Stacking v38: Fix prctl() syscall with + apparmor=0 + + * Fix RPL-U CPU C-state always keep at C3 when system run PHM with idle screen + on (LP: #2042385) + - SAUCE: r8169: Add quirks to enable ASPM on Dell platforms + + * [Debian] autoreconstruct - Do not generate chmod -x for deleted files + (LP: #2045562) + - [Debian] autoreconstruct - Do not generate chmod -x for deleted files + + * Disable Legacy TIOCSTI (LP: #2046192) + - [Config]: disable CONFIG_LEGACY_TIOCSTI + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] remove helper scripts + - [Packaging] update annotations scripts + + * Miscellaneous Ubuntu changes + - [Packaging] rules: Remove unused dkms make variables + - [Config] update annotations after rebase to v6.7-rc8 + + [ Upstream Kernel Changes ] + + * Rebase to v6.7-rc8 + + -- Andrea Righi Tue, 02 Jan 2024 14:57:21 +0100 + +linux-unstable (6.7.0-3.3) noble; urgency=medium + + * noble/linux-unstable: 6.7.0-3.3 -proposed tracker (LP: #2046060) + + * enable CONFIG_INTEL_TDX_HOST in linux >= 6.7 for noble (LP: #2046040) + - [Config] enable CONFIG_INTEL_TDX_HOST + + * linux tools packages for derived kernels refuse to install simultaneously + due to libcpupower name collision (LP: #2035971) + - [Packaging] Statically link libcpupower into cpupower tool + + * make lazy RCU a boot time option (LP: #2045492) + - SAUCE: rcu: Provide a boot time parameter to control lazy RCU + + * Build failure if run in a console (LP: #2044512) + - [Packaging] Fix kernel module compression failures + + * Turning COMPAT_32BIT_TIME off on arm64 (64k & derivatives) (LP: #2038582) + - [Config] y2038: Turn off COMPAT and COMPAT_32BIT_TIME on arm64 64k + + * Turning COMPAT_32BIT_TIME off on riscv64 (LP: #2038584) + - [Config] y2038: Disable COMPAT_32BIT_TIME on riscv64 + + * Turning COMPAT_32BIT_TIME off on ppc64el (LP: #2038587) + - [Config] y2038: Disable COMPAT and COMPAT_32BIT_TIME on ppc64le + + * [UBUNTU 23.04] Kernel config option missing for s390x PCI passthrough + (LP: #2042853) + - [Config] CONFIG_VFIO_PCI_ZDEV_KVM=y + + * back-out zstd module compression automatic for backports (LP: #2045593) + - [Packaging] make ZSTD module compression conditional + + * Miscellaneous Ubuntu changes + - [Packaging] Remove do_full_source variable + - [Packaging] Remove obsolete config handling + - [Packaging] Remove support for sub-flavors + - [Packaging] Remove old linux-libc-dev version hack + - [Packaging] Remove obsolete scripts + - [Packaging] Remove README.inclusion-list + - [Packaging] make $(stampdir)/stamp-build-perarch depend on build-arch + - [Packaging] Enable rootless builds + - [Packaging] Allow to run debian/rules without (fake)root + - [Packaging] remove unneeded trailing slash for INSTALL_MOD_PATH + - [Packaging] override KERNELRELEASE instead of KERNELVERSION + - [Config] update toolchain versions in annotations + - [Packaging] drop useless linux-doc + - [Packaging] scripts: Rewrite insert-ubuntu-changes in Python + - [Packaging] enable riscv64 builds + - [Packaging] remove the last sub-flavours bit + - [Packaging] check debian.env to determine do_libc_dev_package + - [Packaging] remove debian.*/variants + - [Packaging] remove do_libc_dev_package variable + - [Packaging] move linux-libc-dev.stub to debian/control.d/ + - [Packaging] Update check to build linux-libc-dev to the source package name + - [Packaging] rules: Remove startnewrelease target + - [Packaging] Remove debian/commit-templates + - [Config] update annotations after rebase to v6.7-rc4 + + [ Upstream Kernel Changes ] + + * Rebase to v6.7-rc4 + + -- Andrea Righi Mon, 11 Dec 2023 15:56:11 +0100 + +linux-unstable (6.7.0-2.2) noble; urgency=medium + + * noble/linux-unstable: 6.7.0-2.2 -proposed tracker (LP: #2045107) + + * Miscellaneous Ubuntu changes + - [Packaging] re-enable Rust + - [Config] enable Rust in annotations + - [Packaging] Remove do_enforce_all variable + - [Config] disable Softlogic 6x10 capture card driver on armhf + - [Packaging] disable Rust support + - [Config] update annotations after rebase to v6.7-rc3 + + [ Upstream Kernel Changes ] + + * Rebase to v6.7-rc3 + + -- Andrea Righi Wed, 29 Nov 2023 07:51:17 +0100 + +linux-unstable (6.7.0-1.1) noble; urgency=medium + + * noble/linux-unstable: 6.7.0-1.1 -proposed tracker (LP: #2044069) + + * Packaging resync (LP: #1786013) + - [Packaging] update annotations scripts + - [Packaging] update helper scripts + + * Miscellaneous Ubuntu changes + - [Config] update annotations after rebase to v6.7-rc2 + + [ Upstream Kernel Changes ] + + * Rebase to v6.7-rc2 + + -- Andrea Righi Tue, 21 Nov 2023 10:45:24 +0100 + +linux-unstable (6.7.0-0.0) noble; urgency=medium + + * Empty entry + + -- Andrea Righi Tue, 21 Nov 2023 07:26:46 +0100 + +linux-unstable (6.6.0-12.12) noble; urgency=medium + + * noble/linux-unstable: 6.6.0-12.12 -proposed tracker (LP: #2043664) + + * Miscellaneous Ubuntu changes + - [Packaging] temporarily disable zfs dkms + + -- Paolo Pisati Thu, 16 Nov 2023 10:20:26 +0100 + +linux-unstable (6.6.0-11.11) noble; urgency=medium + + * noble/linux-unstable: 6.6.0-11.11 -proposed tracker (LP: #2043480) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + - [Packaging] update variants + - debian/dkms-versions -- update from kernel-versions (main/d2023.11.14) + + * Miscellaneous Ubuntu changes + - [Packaging] move to Noble + - [Config] toolchain version update + + -- Paolo Pisati Wed, 15 Nov 2023 14:50:40 +0100 + +linux-unstable (6.6.0-10.10) noble; urgency=medium + + * mantic/linux-unstable: 6.6.0-10.10 -proposed tracker (LP: #2043088) + + * Bump arm64's CONFIG_NR_CPUS to 512 (LP: #2042897) + - [Config] Bump CONFIG_NR_CPUS to 512 for arm64 + + * Miscellaneous Ubuntu changes + - [Config] Include a note for the NR_CPUS setting on riscv64 + - SAUCE: apparmor4.0.0 [83/83]: Fix inode_init for changed prototype + + -- Paolo Pisati Thu, 09 Nov 2023 12:05:11 +0200 + +linux-unstable (6.6.0-9.9) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-9.9 -proposed tracker (LP: #2041852) + + * Switch IMA default hash to sha256 (LP: #2041735) + - [Config] Switch IMA_DEFAULT_HASH from sha1 to sha256 + + * apparmor restricts read access of user namespace mediation sysctls to root + (LP: #2040194) + - SAUCE: apparmor4.0.0 [82/82]: apparmor: open userns related sysctl so lxc + can check if restriction are in place + + * AppArmor spams kernel log with assert when auditing (LP: #2040192) + - SAUCE: apparmor4.0.0 [81/82]: apparmor: fix request field from a prompt + reply that denies all access + + * apparmor notification files verification (LP: #2040250) + - SAUCE: apparmor4.0.0 [80/82]: apparmor: fix notification header size + + * apparmor oops when racing to retrieve a notification (LP: #2040245) + - SAUCE: apparmor4.0.0 [79/82]: apparmor: fix oops when racing to retrieve + notification + + * Disable restricting unprivileged change_profile by default, due to LXD + latest/stable not yet compatible with this new apparmor feature + (LP: #2038567) + - SAUCE: apparmor4.0.0 [78/82]: apparmor: Make + apparmor_restrict_unprivileged_unconfined opt-in + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [01/82]: add/use fns to print hash string hex value + - SAUCE: apparmor4.0.0 [02/82]: rename SK_CTX() to aa_sock and make it an + inline fn + - SAUCE: apparmor4.0.0 [03/82]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor4.0.0 [04/82]: add user namespace creation mediation + - SAUCE: apparmor4.0.0 [05/82]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor4.0.0 [06/82]: af_unix mediation + - SAUCE: apparmor4.0.0 [07/82]: Add fine grained mediation of posix mqueues + - SAUCE: apparmor4.0.0 [08/82]: Stacking v38: LSM: Identify modules by more + than name + - SAUCE: apparmor4.0.0 [09/82]: Stacking v38: LSM: Add an LSM identifier for + external use + - SAUCE: apparmor4.0.0 [10/82]: Stacking v38: LSM: Identify the process + attributes for each module + - SAUCE: apparmor4.0.0 [11/82]: Stacking v38: LSM: Maintain a table of LSM + attribute data + - SAUCE: apparmor4.0.0 [12/82]: Stacking v38: proc: Use lsmids instead of lsm + names for attrs + - SAUCE: apparmor4.0.0 [13/82]: Stacking v38: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor4.0.0 [14/82]: Stacking v38: LSM: Infrastructure management + of the sock security + - SAUCE: apparmor4.0.0 [15/82]: Stacking v38: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor4.0.0 [16/82]: Stacking v38: LSM: provide lsm name and id + slot mappings + - SAUCE: apparmor4.0.0 [17/82]: Stacking v38: IMA: avoid label collisions with + stacked LSMs + - SAUCE: apparmor4.0.0 [18/82]: Stacking v38: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor4.0.0 [19/82]: Stacking v38: LSM: Use lsmblob in + security_kernel_act_as + - SAUCE: apparmor4.0.0 [20/82]: Stacking v38: LSM: Use lsmblob in + security_secctx_to_secid + - SAUCE: apparmor4.0.0 [21/82]: Stacking v38: LSM: Use lsmblob in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [22/82]: Stacking v38: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor4.0.0 [23/82]: Stacking v38: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor4.0.0 [24/82]: Stacking v38: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor4.0.0 [25/82]: Stacking v38: LSM: Use lsmblob in + security_cred_getsecid + - SAUCE: apparmor4.0.0 [26/82]: Stacking v38: LSM: Specify which LSM to + display + - SAUCE: apparmor4.0.0 [28/82]: Stacking v38: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor4.0.0 [29/82]: Stacking v38: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor4.0.0 [30/82]: Stacking v38: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor4.0.0 [31/82]: Stacking v38: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor4.0.0 [32/82]: Stacking v38: LSM: security_secid_to_secctx in + netlink netfilter + - SAUCE: apparmor4.0.0 [33/82]: Stacking v38: NET: Store LSM netlabel data in + a lsmblob + - SAUCE: apparmor4.0.0 [34/82]: Stacking v38: binder: Pass LSM identifier for + confirmation + - SAUCE: apparmor4.0.0 [35/82]: Stacking v38: LSM: security_secid_to_secctx + module selection + - SAUCE: apparmor4.0.0 [36/82]: Stacking v38: Audit: Keep multiple LSM data in + audit_names + - SAUCE: apparmor4.0.0 [37/82]: Stacking v38: Audit: Create audit_stamp + structure + - SAUCE: apparmor4.0.0 [38/82]: Stacking v38: LSM: Add a function to report + multiple LSMs + - SAUCE: apparmor4.0.0 [39/82]: Stacking v38: Audit: Allow multiple records in + an audit_buffer + - SAUCE: apparmor4.0.0 [40/82]: Stacking v38: Audit: Add record for multiple + task security contexts + - SAUCE: apparmor4.0.0 [41/82]: Stacking v38: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor4.0.0 [42/82]: Stacking v38: Audit: Add record for multiple + object contexts + - SAUCE: apparmor4.0.0 [43/82]: Stacking v38: netlabel: Use a struct lsmblob + in audit data + - SAUCE: apparmor4.0.0 [44/82]: Stacking v38: LSM: Removed scaffolding + function lsmcontext_init + - SAUCE: apparmor4.0.0 [45/82]: Stacking v38: AppArmor: Remove the exclusive + flag + - SAUCE: apparmor4.0.0 [46/82]: combine common_audit_data and + apparmor_audit_data + - SAUCE: apparmor4.0.0 [47/82]: setup slab cache for audit data + - SAUCE: apparmor4.0.0 [48/82]: rename audit_data->label to + audit_data->subj_label + - SAUCE: apparmor4.0.0 [49/82]: pass cred through to audit info. + - SAUCE: apparmor4.0.0 [50/82]: Improve debug print infrastructure + - SAUCE: apparmor4.0.0 [51/82]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor4.0.0 [52/82]: enable userspace upcall for mediation + - SAUCE: apparmor4.0.0 [53/82]: cache buffers on percpu list if there is lock + contention + - SAUCE: apparmor4.0.0 [54/82]: advertise availability of exended perms + - SAUCE: apparmor4.0.0 [56/82]: cleanup: provide separate audit messages for + file and policy checks + - SAUCE: apparmor4.0.0 [57/82]: prompt - lock down prompt interface + - SAUCE: apparmor4.0.0 [58/82]: prompt - ref count pdb + - SAUCE: apparmor4.0.0 [59/82]: prompt - allow controlling of caching of a + prompt response + - SAUCE: apparmor4.0.0 [60/82]: prompt - add refcount to audit_node in prep or + reuse and delete + - SAUCE: apparmor4.0.0 [61/82]: prompt - refactor to moving caching to + uresponse + - SAUCE: apparmor4.0.0 [62/82]: prompt - Improve debug statements + - SAUCE: apparmor4.0.0 [63/82]: prompt - fix caching + - SAUCE: apparmor4.0.0 [64/82]: prompt - rework build to use append fn, to + simplify adding strings + - SAUCE: apparmor4.0.0 [65/82]: prompt - refcount notifications + - SAUCE: apparmor4.0.0 [66/82]: prompt - add the ability to reply with a + profile name + - SAUCE: apparmor4.0.0 [67/82]: prompt - fix notification cache when updating + - SAUCE: apparmor4.0.0 [68/82]: prompt - add tailglob on name for cache + support + - SAUCE: apparmor4.0.0 [69/82]: prompt - allow profiles to set prompts as + interruptible + - SAUCE: apparmor4.0.0 [74/82]: advertise disconnected.path is available + - SAUCE: apparmor4.0.0 [75/82]: fix invalid reference on profile->disconnected + - SAUCE: apparmor4.0.0 [76/82]: add io_uring mediation + - SAUCE: apparmor4.0.0 [77/82]: apparmor: Fix regression in mount mediation + + * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe] + apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic + (LP: #2032602) + - SAUCE: apparmor4.0.0 [70/82]: prompt - add support for advanced filtering of + notifications + - SAUCE: apparmor4.0.0 [71/82]: userns - add the ability to reference a global + variable for a feature value + - SAUCE: apparmor4.0.0 [72/82]: userns - make it so special unconfined + profiles can mediate user namespaces + - SAUCE: apparmor4.0.0 [73/82]: userns - allow restricting unprivileged + change_profile + + * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update + apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor4.0.0 [55/82]: fix profile verification and enable it + + * udev fails to make prctl() syscall with apparmor=0 (as used by maas by + default) (LP: #2016908) // update apparmor and LSM stacking patch set + (LP: #2028253) + - SAUCE: apparmor4.0.0 [27/82]: Stacking v38: Fix prctl() syscall with + apparmor=0 + + * Miscellaneous Ubuntu changes + - [Config] SECURITY_APPARMOR_RESTRICT_USERNS=y + + -- Paolo Pisati Fri, 03 Nov 2023 11:59:12 +0100 + +linux-unstable (6.6.0-8.8) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-8.8 -proposed tracker (LP: #2040243) + + * Miscellaneous Ubuntu changes + - abi: gc reference to phy-rtk-usb2/phy-rtk-usb3 + + -- Paolo Pisati Tue, 24 Oct 2023 10:55:34 +0200 + +linux-unstable (6.6.0-7.7) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-7.7 -proposed tracker (LP: #2040147) + + * test_021_aslr_dapper_libs from ubuntu_qrt_kernel_security failed on K-5.19 / + J-OEM-6.1 / J-6.2 AMD64 (LP: #1983357) + - [Config]: set ARCH_MMAP_RND_{COMPAT_, }BITS to the maximum + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following v6.6-rc7 rebase + + -- Paolo Pisati Mon, 23 Oct 2023 11:51:14 +0200 + +linux-unstable (6.6.0-6.6) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-6.6 -proposed tracker (LP: #2039780) + + * Miscellaneous Ubuntu changes + - rebase on v6.6-rc6 + - [Config] updateconfigs following v6.6-rc6 rebase + + [ Upstream Kernel Changes ] + + * Rebase to v6.6-rc6 + + -- Paolo Pisati Thu, 19 Oct 2023 12:09:16 +0200 + +linux-unstable (6.6.0-5.5) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-5.5 -proposed tracker (LP: #2038899) + + * Miscellaneous Ubuntu changes + - rebase on v6.6-rc5 + - [Config] updateconfigs following v6.6-rc5 rebase + + [ Upstream Kernel Changes ] + + * Rebase to v6.6-rc5 + + -- Paolo Pisati Tue, 10 Oct 2023 11:18:41 +0200 + +linux-unstable (6.6.0-4.4) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-4.4 -proposed tracker (LP: #2038423) + + * Miscellaneous Ubuntu changes + - rebase on v6.6-rc4 + + [ Upstream Kernel Changes ] + + * Rebase to v6.6-rc4 + + -- Paolo Pisati Wed, 04 Oct 2023 11:16:25 +0200 + +linux-unstable (6.6.0-3.3) mantic; urgency=medium + + * mantic/linux-unstable: 6.6.0-3.3 -proposed tracker (LP: #2037622) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following v6.6-rc3 rebase + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: enforce rust availability only on x86_64" + - arm64: rust: Enable Rust support for AArch64 + - arm64: rust: Enable PAC support for Rust. + - arm64: Restrict Rust support to little endian only. + + -- Paolo Pisati Thu, 28 Sep 2023 10:45:38 +0200 + +linux-unstable (6.6.0-2.2) mantic; urgency=medium + + * Miscellaneous upstream changes + - UBUBNTU: [Config] build all COMEDI drivers as modules + + -- Paolo Pisati Mon, 18 Sep 2023 14:42:56 +0200 + +linux-unstable (6.6.0-1.1) mantic; urgency=medium + + * Miscellaneous Ubuntu changes + - [Packaging] move linux to linux-unstable + - [Packaging] rebase on v6.6-rc1 + - [Config] updateconfigs following v6.6-rc1 rebase + - [packaging] skip ABI, modules and retpoline checks + - update dropped.txt + - [Config] SHIFT_FS FTBFS with Linux 6.6, disable it + - [Config] DELL_UART_BACKLIGHT FTBFS with Linux 6.6, disable it + - [Packaging] debian/dkms-versions: temporarily disable dkms + - [Packaging] temporarily disable signing for s390x + + [ Upstream Kernel Changes ] + + * Rebase to v6.6-rc1 + + -- Paolo Pisati Fri, 15 Sep 2023 14:42:18 +0200 + +linux-unstable (6.6.0-0.0) mantic; urgency=medium + + * Empty entry + + -- Paolo Pisati Thu, 14 Sep 2023 15:03:19 +0200 + +linux (6.5.0-5.5) mantic; urgency=medium + + * mantic/linux: 6.5.0-5.5 -proposed tracker (LP: #2034546) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23) + + +linux (6.5.0-4.4) mantic; urgency=medium + + * mantic/linux: 6.5.0-4.4 -proposed tracker (LP: #2034042) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23) + + -- Andrea Righi Mon, 04 Sep 2023 16:55:44 +0200 + +linux (6.5.0-3.3) mantic; urgency=medium + + * mantic/linux: 6.5.0-3.3 -proposed tracker (LP: #2033904) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23) + + * [23.10] Please test secure-boot and lockdown on the early 6.5 kernel (s390x) + (LP: #2026833) + - [Packaging] re-enable signing for s390x + + * Miscellaneous upstream changes + - module/decompress: use vmalloc() for zstd decompression workspace + + -- Andrea Righi Fri, 01 Sep 2023 16:15:33 +0200 + +linux (6.5.0-2.2) mantic; urgency=medium + + * mantic/linux: 6.5.0-2.2 -proposed tracker (LP: #2033240) + + * Soundwire support for Dell SKU0C87 devices (LP: #2029281) + - SAUCE: ASoC: Intel: soc-acpi: add support for Dell SKU0C87 devices + + * Fix numerous AER related issues (LP: #2033025) + - SAUCE: PCI/AER: Disable AER service during suspend, again + - SAUCE: PCI/DPC: Disable DPC service during suspend, again + + * Support Realtek RTL8852CE WiFi 6E/BT Combo (LP: #2025672) + - wifi: rtw89: debug: Fix error handling in rtw89_debug_priv_btc_manual_set() + - Bluetooth: btrtl: Load FW v2 otherwise FW v1 for RTL8852C + + [ Upstream Kernel Changes ] + + * Rebase to v6.5 + + -- Andrea Righi Mon, 28 Aug 2023 08:53:19 +0200 + +linux (6.5.0-1.1) mantic; urgency=medium + + * mantic/linux: 6.5.0-1.1 -proposed tracker (LP: #2032750) + + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - [Packaging] update variants + - debian/dkms-versions -- update from kernel-versions (main/d2023.07.26) + + * ceph: support idmapped mounts (LP: #2032959) + - SAUCE: libceph: add spinlock around osd->o_requests + - SAUCE: libceph: define struct ceph_sparse_extent and add some helpers + - SAUCE: libceph: new sparse_read op, support sparse reads on msgr2 crc + codepath + - SAUCE: libceph: support sparse reads on msgr2 secure codepath + - SAUCE: libceph: add sparse read support to msgr1 + - SAUCE: libceph: add sparse read support to OSD client + - SAUCE: ceph: add new mount option to enable sparse reads + - SAUCE: ceph: preallocate inode for ops that may create one + - SAUCE: ceph: make ceph_msdc_build_path use ref-walk + - SAUCE: libceph: add new iov_iter-based ceph_msg_data_type and + ceph_osd_data_type + - SAUCE: ceph: use osd_req_op_extent_osd_iter for netfs reads + - SAUCE: ceph: fscrypt_auth handling for ceph + - SAUCE: ceph: implement -o test_dummy_encryption mount option + - SAUCE: ceph: add fscrypt ioctls and ceph.fscrypt.auth vxattr + - SAUCE: ceph: make ioctl cmds more readable in debug log + - SAUCE: ceph: add base64 endcoding routines for encrypted names + - SAUCE: ceph: encode encrypted name in ceph_mdsc_build_path and dentry + release + - SAUCE: ceph: send alternate_name in MClientRequest + - SAUCE: ceph: decode alternate_name in lease info + - SAUCE: ceph: set DCACHE_NOKEY_NAME flag in ceph_lookup/atomic_open() + - SAUCE: ceph: make d_revalidate call fscrypt revalidator for encrypted + dentries + - SAUCE: ceph: add helpers for converting names for userland presentation + - SAUCE: ceph: make ceph_fill_trace and ceph_get_name decrypt names + - SAUCE: ceph: pass the request to parse_reply_info_readdir() + - SAUCE: ceph: add support to readdir for encrypted names + - SAUCE: ceph: create symlinks with encrypted and base64-encoded targets + - SAUCE: ceph: add some fscrypt guardrails + - SAUCE: ceph: allow encrypting a directory while not having Ax caps + - SAUCE: ceph: mark directory as non-complete after loading key + - SAUCE: ceph: size handling in MClientRequest, cap updates and inode traces + - SAUCE: ceph: handle fscrypt fields in cap messages from MDS + - SAUCE: ceph: add infrastructure for file encryption and decryption + - SAUCE: libceph: add CEPH_OSD_OP_ASSERT_VER support + - SAUCE: libceph: allow ceph_osdc_new_request to accept a multi-op read + - SAUCE: ceph: add object version support for sync read + - SAUCE: ceph: add truncate size handling support for fscrypt + - SAUCE: ceph: don't use special DIO path for encrypted inodes + - SAUCE: ceph: align data in pages in ceph_sync_write + - SAUCE: ceph: add read/modify/write to ceph_sync_write + - SAUCE: ceph: add encryption support to writepage and writepages + - SAUCE: ceph: plumb in decryption during reads + - SAUCE: ceph: invalidate pages when doing direct/sync writes + - SAUCE: ceph: add support for encrypted snapshot names + - SAUCE: ceph: prevent snapshot creation in encrypted locked directories + - SAUCE: ceph: update documentation regarding snapshot naming limitations + - SAUCE: ceph: drop messages from MDS when unmounting + - SAUCE: ceph: wait for OSD requests' callbacks to finish when unmounting + - SAUCE: ceph: fix updating i_truncate_pagecache_size for fscrypt + - SAUCE: ceph: switch ceph_lookup/atomic_open() to use new fscrypt helper + - SAUCE: libceph: do not include crypto/algapi.h + - SAUCE: rbd: bump RBD_MAX_PARENT_CHAIN_LEN to 128 + - SAUCE: ceph: dump info about cap flushes when we're waiting too long for + them + - SAUCE: mm: BUG if filemap_alloc_folio gives us a folio with a non-NULL + ->private + - SAUCE: ceph: make sure all the files successfully put before unmounting + - SAUCE: ceph: BUG if MDS changed truncate_seq with client caps still + outstanding + - SAUCE: ceph: add the *_client debug macros support + - SAUCE: ceph: pass the mdsc to several helpers + - SAUCE: ceph: rename _to_client() to _to_fs_client() + - SAUCE: ceph: move mdsmap.h to fs/ceph/ + - SAUCE: ceph: add ceph_inode_to_client() helper support + - SAUCE: ceph: print the client global_id in all the debug logs + - SAUCE: ceph: make the members in struct ceph_mds_request_args_ext an union + - SAUCE: ceph: make num_fwd and num_retry to __u32 + - SAUCE: fs: export mnt_idmap_get/mnt_idmap_put + - SAUCE: ceph: stash idmapping in mdsc request + - SAUCE: ceph: handle idmapped mounts in create_request_message() + - SAUCE: ceph: add enable_unsafe_idmap module parameter + - SAUCE: ceph: pass an idmapping to mknod/symlink/mkdir + - SAUCE: ceph: allow idmapped getattr inode op + - SAUCE: ceph: allow idmapped permission inode op + - SAUCE: ceph: pass idmap to __ceph_setattr + - SAUCE: ceph: allow idmapped setattr inode op + - SAUCE: ceph/acl: allow idmapped set_acl inode op + - SAUCE: ceph/file: allow idmapped atomic_open inode op + - SAUCE: ceph: allow idmapped mounts + + * Got soft lockup CPU if dell_uart_backlight is probed (LP: #2032174) + - SAUCE: platform/x86: dell-uart-backlight: replace chars_in_buffer() with + flush_chars() + + * Fix ACPI TAD on some Intel based systems (LP: #2032767) + - ACPI: TAD: Install SystemCMOS address space handler for ACPI000E + + * Fix unreliable ethernet cable detection on I219 NIC (LP: #2028122) + - e1000e: Use PME poll to circumvent unreliable ACPI wake + + * Fix panel brightness issues on HP laptops (LP: #2032704) + - ACPI: video: Put ACPI video and its child devices into D0 on boot + + * FATAL:credentials.cc(127)] Check failed: . : Permission denied (13) + (LP: #2017980) + - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * Support initrdless boot on default qemu virt models and openstack + (LP: #2030745) + - [Config] set VIRTIO_BLK=y for default qemu/openstack boot + + * Miscellaneous Ubuntu changes + - [Packaging] rust: use Rust 1.68.2 + - [Packaging] depend on clang/libclang-15 for Rust + - [Config] update toolchain versions in annotations + - [Config] update annotations after rebase to v6.5-rc6 + - [Config] update toolchain version in annotations + - [Packaging] temporarily disable Rust support + - [Packaging] temporarily disable signing for ppc64el + - [Packaging] temporarily disable signing for s390x + + -- Andrea Righi Thu, 24 Aug 2023 17:47:10 +0200 + +linux (6.5.0-0.0) mantic; urgency=medium + + * Empty entry + + -- Andrea Righi Wed, 23 Aug 2023 08:14:48 +0200 + +linux-unstable (6.5.0-4.4) mantic; urgency=medium + + * mantic/linux-unstable: 6.5.0-4.4 -proposed tracker (LP: #2029086) + + * Miscellaneous Ubuntu changes + - [Packaging] Add .NOTPARALLEL + - [Packaging] Remove meaningless $(header_arch) + - [Packaging] Fix File exists error in install-arch-headers + - [Packaging] clean debian/linux-* directories + - [Packaging] remove hmake + - [Packaging] install headers to debian/linux-libc-dev directly + - [Config] define CONFIG options for arm64 instead of arm64-generic + - [Config] update annotations after rebase to v6.5-rc4 + - [Packaging] temporarily disable Rust support + + [ Upstream Kernel Changes ] + + * Rebase to v6.5-rc4 + + -- Andrea Righi Mon, 31 Jul 2023 08:41:59 +0200 + +linux-unstable (6.5.0-3.3) mantic; urgency=medium + + * mantic/linux-unstable: 6.5.0-3.3 -proposed tracker (LP: #2028779) + + * enable Rust support in the kernel (LP: #2007654) + - SAUCE: rust: support rustc-1.69.0 + - [Packaging] depend on rustc-1.69.0 + + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - [Packaging] resync getabis + + * Fix UBSAN in Intel EDAC driver (LP: #2028746) + - EDAC/i10nm: Skip the absent memory controllers + + * Ship kernel modules Zstd compressed (LP: #2028568) + - SAUCE: Support but do not require compressed modules + - [Config] Enable support for ZSTD compressed modules + - [Packaging] ZSTD compress modules + + * update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor3.2.0 [02/60]: rename SK_CTX() to aa_sock and make it an + inline fn + - SAUCE: apparmor3.2.0 [05/60]: Add sysctls for additional controls of unpriv + userns restrictions + - SAUCE: apparmor3.2.0 [08/60]: Stacking v38: LSM: Identify modules by more + than name + - SAUCE: apparmor3.2.0 [09/60]: Stacking v38: LSM: Add an LSM identifier for + external use + - SAUCE: apparmor3.2.0 [10/60]: Stacking v38: LSM: Identify the process + attributes for each module + - SAUCE: apparmor3.2.0 [11/60]: Stacking v38: LSM: Maintain a table of LSM + attribute data + - SAUCE: apparmor3.2.0 [12/60]: Stacking v38: proc: Use lsmids instead of lsm + names for attrs + - SAUCE: apparmor3.2.0 [13/60]: Stacking v38: integrity: disassociate + ima_filter_rule from security_audit_rule + - SAUCE: apparmor3.2.0 [14/60]: Stacking v38: LSM: Infrastructure management + of the sock security + - SAUCE: apparmor3.2.0 [15/60]: Stacking v38: LSM: Add the lsmblob data + structure. + - SAUCE: apparmor3.2.0 [16/60]: Stacking v38: LSM: provide lsm name and id + slot mappings + - SAUCE: apparmor3.2.0 [17/60]: Stacking v38: IMA: avoid label collisions with + stacked LSMs + - SAUCE: apparmor3.2.0 [18/60]: Stacking v38: LSM: Use lsmblob in + security_audit_rule_match + - SAUCE: apparmor3.2.0 [19/60]: Stacking v38: LSM: Use lsmblob in + security_kernel_act_as + - SAUCE: apparmor3.2.0 [20/60]: Stacking v38: LSM: Use lsmblob in + security_secctx_to_secid + - SAUCE: apparmor3.2.0 [21/60]: Stacking v38: LSM: Use lsmblob in + security_secid_to_secctx + - SAUCE: apparmor3.2.0 [22/60]: Stacking v38: LSM: Use lsmblob in + security_ipc_getsecid + - SAUCE: apparmor3.2.0 [23/60]: Stacking v38: LSM: Use lsmblob in + security_current_getsecid + - SAUCE: apparmor3.2.0 [24/60]: Stacking v38: LSM: Use lsmblob in + security_inode_getsecid + - SAUCE: apparmor3.2.0 [25/60]: Stacking v38: LSM: Use lsmblob in + security_cred_getsecid + - SAUCE: apparmor3.2.0 [26/60]: Stacking v38: LSM: Specify which LSM to + display + - SAUCE: apparmor3.2.0 [28/60]: Stacking v38: LSM: Ensure the correct LSM + context releaser + - SAUCE: apparmor3.2.0 [29/60]: Stacking v38: LSM: Use lsmcontext in + security_secid_to_secctx + - SAUCE: apparmor3.2.0 [30/60]: Stacking v38: LSM: Use lsmcontext in + security_inode_getsecctx + - SAUCE: apparmor3.2.0 [31/60]: Stacking v38: Use lsmcontext in + security_dentry_init_security + - SAUCE: apparmor3.2.0 [32/60]: Stacking v38: LSM: security_secid_to_secctx in + netlink netfilter + - SAUCE: apparmor3.2.0 [33/60]: Stacking v38: NET: Store LSM netlabel data in + a lsmblob + - SAUCE: apparmor3.2.0 [34/60]: Stacking v38: binder: Pass LSM identifier for + confirmation + - SAUCE: apparmor3.2.0 [35/60]: Stacking v38: LSM: security_secid_to_secctx + module selection + - SAUCE: apparmor3.2.0 [36/60]: Stacking v38: Audit: Keep multiple LSM data in + audit_names + - SAUCE: apparmor3.2.0 [37/60]: Stacking v38: Audit: Create audit_stamp + structure + - SAUCE: apparmor3.2.0 [38/60]: Stacking v38: LSM: Add a function to report + multiple LSMs + - SAUCE: apparmor3.2.0 [39/60]: Stacking v38: Audit: Allow multiple records in + an audit_buffer + - SAUCE: apparmor3.2.0 [40/60]: Stacking v38: Audit: Add record for multiple + task security contexts + - SAUCE: apparmor3.2.0 [41/60]: Stacking v38: audit: multiple subject lsm + values for netlabel + - SAUCE: apparmor3.2.0 [42/60]: Stacking v38: Audit: Add record for multiple + object contexts + - SAUCE: apparmor3.2.0 [43/60]: Stacking v38: netlabel: Use a struct lsmblob + in audit data + - SAUCE: apparmor3.2.0 [44/60]: Stacking v38: LSM: Removed scaffolding + function lsmcontext_init + - SAUCE: apparmor3.2.0 [45/60]: Stacking v38: AppArmor: Remove the exclusive + flag + - SAUCE: apparmor3.2.0 [46/60]: combine common_audit_data and + apparmor_audit_data + - SAUCE: apparmor3.2.0 [47/60]: setup slab cache for audit data + - SAUCE: apparmor3.2.0 [48/60]: rename audit_data->label to + audit_data->subj_label + - SAUCE: apparmor3.2.0 [49/60]: pass cred through to audit info. + - SAUCE: apparmor3.2.0 [50/60]: Improve debug print infrastructure + - SAUCE: apparmor3.2.0 [51/60]: add the ability for profiles to have a + learning cache + - SAUCE: apparmor3.2.0 [52/60]: enable userspace upcall for mediation + - SAUCE: apparmor3.2.0 [53/60]: cache buffers on percpu list if there is lock + contention + - SAUCE: apparmor3.2.0 [55/60]: advertise availability of exended perms + - SAUCE: apparmor3.2.0 [60/60]: [Config] enable + CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update + apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor3.2.0 [57/60]: fix profile verification and enable it + + * udev fails to make prctl() syscall with apparmor=0 (as used by maas by + default) (LP: #2016908) // update apparmor and LSM stacking patch set + (LP: #2028253) + - SAUCE: apparmor3.2.0 [27/60]: Stacking v38: Fix prctl() syscall with + apparmor=0 + + * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) // + update apparmor and LSM stacking patch set (LP: #2028253) + - SAUCE: apparmor3.2.0 [01/60]: add/use fns to print hash string hex value + - SAUCE: apparmor3.2.0 [03/60]: patch to provide compatibility with v2.x net + rules + - SAUCE: apparmor3.2.0 [04/60]: add user namespace creation mediation + - SAUCE: apparmor3.2.0 [06/60]: af_unix mediation + - SAUCE: apparmor3.2.0 [07/60]: Add fine grained mediation of posix mqueues + + * Miscellaneous Ubuntu changes + - [Packaging] Use consistent llvm/clang for rust + + [ Upstream Kernel Changes ] + + * Rebase to v6.5-rc3 + + -- Andrea Righi Fri, 28 Jul 2023 07:44:20 +0200 + +linux-unstable (6.5.0-2.2) mantic; urgency=medium + + * mantic/linux-unstable: 6.5.0-2.2 -proposed tracker (LP: #2027953) + + * Remove non-LPAE kernel flavor (LP: #2025265) + - [Packaging] Rename armhf generic-lpae flavor to generic + + * Please enable Renesas RZ platform serial installer (LP: #2022361) + - [Config] enable hihope RZ/G2M serial console + + * Miscellaneous Ubuntu changes + - [Packaging] snap: Remove old configs handling + - [Packaging] checks/final-checks: Remove old configs handling + - [Packaging] checks/final-checks: check existance of Makefile first + - [Packaging] checks/final-checks: Fix shellcheck issues + - [Packaging] add libstdc++-dev to the build dependencies + - [Config] update annotations after rebase to v6.5-rc2 + + * Miscellaneous upstream changes + - kbuild: rust: avoid creating temporary files + - rust: fix bindgen build error with UBSAN_BOUNDS_STRICT + + [ Upstream Kernel Changes ] + + * Rebase to v6.5-rc2 + + -- Andrea Righi Tue, 18 Jul 2023 10:14:14 +0200 + +linux-unstable (6.5.0-1.1) mantic; urgency=medium + + * mantic/linux-unstable: 6.5.0-1.1 -proposed tracker (LP: #2026689) + + * CVE-2023-31248 + - netfilter: nf_tables: do not ignore genmask when looking up chain by id + + * CVE-2023-35001 + - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval + + * HDMI output with More than one child device for port B in VBT error + (LP: #2025195) + - SAUCE: drm/i915/quirks: Add multiple VBT quirk for HP ZBook Power G10 + + * CVE-2023-2640 // CVE-2023-32629 + - SAUCE: overlayfs: default to userxattr when mounted from non initial user + namespace + + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + + * enable Rust support in the kernel (LP: #2007654) + - SAUCE: btf, scripts: rust: drop is_rust_module.sh + - [Packaging] add rust dependencies + + * CVE-2023-2612 + - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object() + + * Miscellaneous Ubuntu changes + - SAUCE: shiftfs: support linux 6.5 + - [Config] update annotations after rebase to v6.5-rc1 + - [Config] temporarily disable Rust + + [ Upstream Kernel Changes ] + + * Rebase to v6.5-rc1 + + -- Andrea Righi Mon, 10 Jul 2023 09:15:26 +0200 + +linux-unstable (6.5.0-0.0) mantic; urgency=medium + + * Empty entry + + -- Andrea Righi Wed, 05 Jul 2023 12:48:39 +0200 + +linux-unstable (6.4.0-8.8) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-8.8 -proposed tracker (LP: #2025018) + + * Miscellaneous Ubuntu changes + - [Config] update toolchain version (gcc) in annotations + + [ Upstream Kernel Changes ] + + * Rebase to v6.4 + + -- Andrea Righi Mon, 26 Jun 2023 09:14:02 +0200 + +linux-unstable (6.4.0-7.7) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-7.7 -proposed tracker (LP: #2024338) + + [ Upstream Kernel Changes ] + + * Rebase to v6.4-rc7 + + -- Andrea Righi Mon, 19 Jun 2023 08:51:27 +0200 + +linux-unstable (6.4.0-6.6) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-6.6 -proposed tracker (LP: #2023966) + + * Packaging resync (LP: #1786013) + - [Packaging] update annotations scripts + + * enable multi-gen LRU by default (LP: #2023629) + - [Config] enable multi-gen LRU by default + + * Fix Monitor lost after replug WD19TBS to SUT port with VGA/DVI to type-C + dongle (LP: #2021949) + - thunderbolt: Do not touch CL state configuration during discovery + - thunderbolt: Increase DisplayPort Connection Manager handshake timeout + + * Neuter signing tarballs (LP: #2012776) + - [Packaging] remove the signing tarball support + + * Enable Tracing Configs for OSNOISE and TIMERLAT (LP: #2018591) + - [Config] Enable OSNOISE_TRACER and TIMERLAT_TRACER configs + + * Miscellaneous Ubuntu changes + - [Config] Add CONFIG_AS_HAS_NON_CONST_LEB128 on riscv64 + - [Packaging] introduce do_lib_rust and enable it only on generic amd64 + - [Config] update annotations after rebase to v6.4-rc6 + + [ Upstream Kernel Changes ] + + * Rebase to v6.4-rc6 + + -- Andrea Righi Thu, 15 Jun 2023 20:11:07 +0200 + +linux-unstable (6.4.0-5.5) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-5.5 -proposed tracker (LP: #2022886) + + * Miscellaneous Ubuntu changes + - [Packaging] update getabis to support linux-unstable + - UBUNTU [Config]: disable hibernation on riscv64 + + [ Upstream Kernel Changes ] + + * Rebase to v6.4-rc5 + + -- Andrea Righi Tue, 06 Jun 2023 08:18:01 +0200 + +linux-unstable (6.4.0-4.4) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-4.4 -proposed tracker (LP: #2021597) + + * Miscellaneous Ubuntu changes + - [Config] udpate annotations after rebase to v6.4-rc4 + + -- Andrea Righi Tue, 30 May 2023 11:55:41 +0200 + +linux-unstable (6.4.0-3.3) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-3.3 -proposed tracker (LP: #2021497) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync getabis + + * support python < 3.9 with annotations (LP: #2020531) + - [Packaging] kconfig/annotations.py: support older way of merging dicts + + * generate linux-lib-rust only on amd64 (LP: #2020356) + - [Packaging] generate linux-lib-rust only on amd64 + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: never drop configs that have notes different than + the parent + - [Config] drop CONFIG_SMBFS_COMMON from annotations + - [Packaging] perf: build without libtraceevent + + [ Upstream Kernel Changes ] + + * Rebase to v6.4-rc4 + + -- Andrea Righi Tue, 30 May 2023 08:38:10 +0200 + +linux-unstable (6.4.0-2.2) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-2.2 -proposed tracker (LP: #2020330) + + * Computer with Intel Atom CPU will not boot with Kernel 6.2.0-20 + (LP: #2017444) + - [Config]: Disable CONFIG_INTEL_ATOMISP + + * Fix NVME storage with RAID ON disappeared under Dell factory WINPE + environment (LP: #2011768) + - SAUCE: PCI: vmd: Reset VMD config register between soft reboots + + * Miscellaneous Ubuntu changes + - [Packaging] Drop support of old config handling + - [Config] update annotations after rebase to v6.4-rc3 + + [ Upstream Kernel Changes ] + + * Rebase to v6.4-rc3 + + -- Andrea Righi Mon, 22 May 2023 11:22:14 +0200 + +linux-unstable (6.4.0-1.1) mantic; urgency=medium + + * mantic/linux-unstable: 6.4.0-1.1 -proposed tracker (LP: #2019965) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update helper scripts + + * Kernel 6.1 bumped the disk consumption on default images by 15% + (LP: #2015867) + - [Packaging] introduce a separate linux-lib-rust package + + * Miscellaneous Ubuntu changes + - [Config] enable CONFIG_BLK_DEV_UBLK on amd64 + - [Packaging] annotations: use python3 in the shebang + - SAUCE: blk-throttle: Fix io statistics for cgroup v1 + - [Packaging] move to v6.4 and rename to linux-unstable + - [Config] update annotations after rebase to v6.4-rc1 + - [Packaging] temporarily disable perf + - [Packaging] temporarily disable bpftool + - [Config] ppc64el: reduce CONFIG_ARCH_FORCE_MAX_ORDER from 9 to 8 + - SAUCE: perf: explicitly disable libtraceevent + + [ Upstream Kernel Changes ] + + * Rebase to v6.4-rc2 + + -- Andrea Righi Thu, 18 May 2023 07:34:09 +0200 + +linux-unstable (6.4.0-0.0) mantic; urgency=medium + + * Empty entry + + -- Andrea Righi Wed, 17 May 2023 15:29:25 +0200 + +linux-unstable (6.3.0-2.2) lunar; urgency=medium + + * lunar/linux-unstable: 6.3.0-2.2 -proposed tracker (LP: #2017788) + + * Miscellaneous Ubuntu changes + - [Packaging] move python3-dev to build-depends + + -- Andrea Righi Wed, 26 Apr 2023 21:52:12 +0200 + +linux-unstable (6.3.0-1.1) lunar; urgency=medium + + * lunar/linux-unstable: 6.3.0-1.1 -proposed tracker (LP: #2017776) + + * RFC: virtio and virtio-scsi should be built in (LP: #1685291) + - [Config] Mark CONFIG_SCSI_VIRTIO built-in + + * Debian autoreconstruct Fix restoration of execute permissions (LP: #2015498) + - [Debian] autoreconstruct - fix restoration of execute permissions + + * [SRU][Jammy] CONFIG_PCI_MESON is not enabled (LP: #2007745) + - [Config] arm64: Enable PCI_MESON module + + * vmd may fail to create sysfs entry while `pci_rescan_bus()` called in some + other drivers like wwan (LP: #2011389) + - SAUCE: PCI: vmd: guard device addition and removal + + * Lunar update: v6.2.9 upstream stable release (LP: #2016877) + - [Config] ppc64: updateconfigs following v6.2.9 stable updates + + * Lunar update: v6.2.8 upstream stable release (LP: #2016876) + - [Config] ppc64: updateconfigs following v6.2.8 stable updates + + * Miscellaneous Ubuntu changes + - [Packaging] Move final-checks script to debian/scripts/checks + - [Packaging] checks/final-checks: Honor 'do_skip_checks' + - [Packaging] Drop wireguard DKMS + - [Packaging] Remove update-version-dkms + - [Packaging] debian/rules: Add DKMS info to 'printenv' output + - [Packaging] ignore KBUILD_VERBOSE in arch-has-odm-enabled.sh + - SAUCE: shiftfs: support linux 6.3 + - [Packaging] move to v6.3 and rename to linux-unstable + - [Config] latency-related optimizations + - [Config] update annotations after rebase to v6.3 + - [Packaging] temporarily disable dkms + + [ Upstream Kernel Changes ] + + * Rebase to v6.3 + + -- Andrea Righi Wed, 26 Apr 2023 14:53:52 +0200 + +linux-unstable (6.3.0-0.0) lunar; urgency=medium + + * Empty entry + + -- Andrea Righi Tue, 25 Apr 2023 10:24:12 +0200 + +linux (6.2.0-21.21) lunar; urgency=medium + + * lunar/linux: 6.2.0-21.21 -proposed tracker (LP: #2016249) + + * efivarfs:efivarfs.sh in ubuntu_kernel_selftests crash L-6.2 ARM64 node + dazzle (rcu_preempt detected stalls) (LP: #2015741) + - efi/libstub: smbios: Use length member instead of record struct size + - arm64: efi: Use SMBIOS processor version to key off Ampere quirk + - efi/libstub: smbios: Drop unused 'recsize' parameter + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/bpf: ignore pointer types check with clang + - SAUCE: selftests/bpf: avoid conflicting data types in profiler.inc.h + - [Packaging] get rid of unnecessary artifacts in linux-headers + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: Revert "efi: random: refresh non-volatile random seed + when RNG is initialized"" + - Revert "UBUNTU: SAUCE: Revert "efi: random: fix NULL-deref when refreshing + seed"" + + -- Andrea Righi Fri, 14 Apr 2023 12:11:49 +0200 + +linux (6.2.0-20.20) lunar; urgency=medium + + * lunar/linux: 6.2.0-20.20 -proposed tracker (LP: #2015429) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/master) + + * FTBFS with different dkms or when makeflags are set (LP: #2015361) + - [Packaging] FTBFS with different dkms or when makeflags are set + + * expoline.o is packaged unconditionally for s390x (LP: #2013209) + - [Packaging] Copy expoline.o only when produced by the build + + * net:l2tp.sh failure with lunar:linux 6.2 (LP: #2013014) + - SAUCE: l2tp: generate correct module alias strings + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: prevent duplicate include lines + + -- Andrea Righi Thu, 06 Apr 2023 08:33:14 +0200 + +linux (6.2.0-19.19) lunar; urgency=medium + + * lunar/linux: 6.2.0-19.19 -proposed tracker (LP: #2012488) + + * Neuter signing tarballs (LP: #2012776) + - [Packaging] neuter the signing tarball + + * LSM stacking and AppArmor refresh for 6.2 kernel (LP: #2012136) + - Revert "UBUNTU: [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS" + - Revert "UBUNTU: SAUCE: apparmor: add user namespace creation mediation" + - Revert "UBUNTU: SAUCE: apparmor: Add fine grained mediation of posix + mqueues" + - Revert "UBUNTU: SAUCE: Revert "apparmor: make __aa_path_perm() static"" + - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display (using struct cred + as input)" + - Revert "UBUNTU: SAUCE: apparmor: Fix build error, make sk parameter const" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in smk_netlbl_mls()" + - Revert "UBUNTU: SAUCE: LSM: change ima_read_file() to use lsmblob" + - Revert "UBUNTU: SAUCE: apparmor: rename kzfree() to kfree_sensitive()" + - Revert "UBUNTU: SAUCE: AppArmor: Remove the exclusive flag" + - Revert "UBUNTU: SAUCE: LSM: Add /proc attr entry for full LSM context" + - Revert "UBUNTU: SAUCE: Audit: Fix incorrect static inline function + declration." + - Revert "UBUNTU: SAUCE: Audit: Fix for missing NULL check" + - Revert "UBUNTU: SAUCE: Audit: Add a new record for multiple object LSM + attributes" + - Revert "UBUNTU: SAUCE: Audit: Add new record for multiple process LSM + attributes" + - Revert "UBUNTU: SAUCE: NET: Store LSM netlabel data in a lsmblob" + - Revert "UBUNTU: SAUCE: LSM: security_secid_to_secctx in netlink netfilter" + - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_inode_getsecctx" + - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_secid_to_secctx" + - Revert "UBUNTU: SAUCE: LSM: Ensure the correct LSM context releaser" + - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display" + - Revert "UBUNTU: SAUCE: IMA: Change internal interfaces to use lsmblobs" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_cred_getsecid" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_inode_getsecid" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_task_getsecid" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_ipc_getsecid" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secid_to_secctx" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secctx_to_secid" + - Revert "UBUNTU: SAUCE: net: Prepare UDS for security module stacking" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_kernel_act_as" + - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_audit_rule_match" + - Revert "UBUNTU: SAUCE: LSM: Create and manage the lsmblob data structure." + - Revert "UBUNTU: SAUCE: LSM: Infrastructure management of the sock security" + - Revert "UBUNTU: SAUCE: apparmor: LSM stacking: switch from SK_CTX() to + aa_sock()" + - Revert "UBUNTU: SAUCE: apparmor: rename aa_sock() to aa_unix_sk()" + - Revert "UBUNTU: SAUCE: apparmor: disable showing the mode as part of a secid + to secctx" + - Revert "UBUNTU: SAUCE: apparmor: fix use after free in sk_peer_label" + - Revert "UBUNTU: SAUCE: apparmor: af_unix mediation" + - Revert "UBUNTU: SAUCE: apparmor: patch to provide compatibility with v2.x + net rules" + - Revert "UBUNTU: SAUCE: apparmor: add/use fns to print hash string hex value" + - SAUCE: apparmor: rename SK_CTX() to aa_sock and make it an inline fn + - SAUCE: apparmor: Add sysctls for additional controls of unpriv userns + restrictions + - SAUCE: Stacking v38: LSM: Identify modules by more than name + - SAUCE: Stacking v38: LSM: Add an LSM identifier for external use + - SAUCE: Stacking v38: LSM: Identify the process attributes for each module + - SAUCE: Stacking v38: LSM: Maintain a table of LSM attribute data + - SAUCE: Stacking v38: proc: Use lsmids instead of lsm names for attrs + - SAUCE: Stacking v38: integrity: disassociate ima_filter_rule from + security_audit_rule + - SAUCE: Stacking v38: LSM: Infrastructure management of the sock security + - SAUCE: Stacking v38: LSM: Add the lsmblob data structure. + - SAUCE: Stacking v38: LSM: provide lsm name and id slot mappings + - SAUCE: Stacking v38: IMA: avoid label collisions with stacked LSMs + - SAUCE: Stacking v38: LSM: Use lsmblob in security_audit_rule_match + - SAUCE: Stacking v38: LSM: Use lsmblob in security_kernel_act_as + - SAUCE: Stacking v38: LSM: Use lsmblob in security_secctx_to_secid + - SAUCE: Stacking v38: LSM: Use lsmblob in security_secid_to_secctx + - SAUCE: Stacking v38: LSM: Use lsmblob in security_ipc_getsecid + - SAUCE: Stacking v38: LSM: Use lsmblob in security_current_getsecid + - SAUCE: Stacking v38: LSM: Use lsmblob in security_inode_getsecid + - SAUCE: Stacking v38: LSM: Use lsmblob in security_cred_getsecid + - SAUCE: Stacking v38: LSM: Specify which LSM to display + - SAUCE: Stacking v38: LSM: Ensure the correct LSM context releaser + - SAUCE: Stacking v38: LSM: Use lsmcontext in security_secid_to_secctx + - SAUCE: Stacking v38: LSM: Use lsmcontext in security_inode_getsecctx + - SAUCE: Stacking v38: Use lsmcontext in security_dentry_init_security + - SAUCE: Stacking v38: LSM: security_secid_to_secctx in netlink netfilter + - SAUCE: Stacking v38: NET: Store LSM netlabel data in a lsmblob + - SAUCE: Stacking v38: binder: Pass LSM identifier for confirmation + - SAUCE: Stacking v38: LSM: security_secid_to_secctx module selection + - SAUCE: Stacking v38: Audit: Keep multiple LSM data in audit_names + - SAUCE: Stacking v38: Audit: Create audit_stamp structure + - SAUCE: Stacking v38: LSM: Add a function to report multiple LSMs + - SAUCE: Stacking v38: Audit: Allow multiple records in an audit_buffer + - SAUCE: Stacking v38: Audit: Add record for multiple task security contexts + - SAUCE: Stacking v38: audit: multiple subject lsm values for netlabel + - SAUCE: Stacking v38: Audit: Add record for multiple object contexts + - SAUCE: Stacking v38: netlabel: Use a struct lsmblob in audit data + - SAUCE: Stacking v38: LSM: Removed scaffolding function lsmcontext_init + - SAUCE: Stacking v38: AppArmor: Remove the exclusive flag + - SAUCE: apparmor: combine common_audit_data and apparmor_audit_data + - SAUCE: apparmor: setup slab cache for audit data + - SAUCE: apparmor: rename audit_data->label to audit_data->subj_label + - SAUCE: apparmor: pass cred through to audit info. + - SAUCE: apparmor: Improve debug print infrastructure + - SAUCE: apparmor: add the ability for profiles to have a learning cache + - SAUCE: apparmor: enable userspace upcall for mediation + - SAUCE: apparmor: cache buffers on percpu list if there is lock contention + - SAUCE: apparmor: fix policy_compat permission remap with extended + permissions + - SAUCE: apparmor: advertise availability of exended perms + - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + + * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) // LSM + stacking and AppArmor refresh for 6.2 kernel (LP: #2012136) + - SAUCE: apparmor: add/use fns to print hash string hex value + - SAUCE: apparmor: patch to provide compatibility with v2.x net rules + - SAUCE: apparmor: add user namespace creation mediation + - SAUCE: apparmor: af_unix mediation + - SAUCE: apparmor: Add fine grained mediation of posix mqueues + + * devlink_port_split from ubuntu_kernel_selftests.net fails on hirsute + (KeyError: 'flavour') (LP: #1937133) + - selftests: net: devlink_port_split.py: skip test if no suitable device + available + + * NFS deathlock with last Kernel 5.4.0-144.161 and 5.15.0-67.74 (LP: #2009325) + - NFS: Correct timing for assigning access cache timestamp + + -- Andrea Righi Sat, 25 Mar 2023 07:37:30 +0100 + +linux (6.2.0-18.18) lunar; urgency=medium + + * lunar/linux: 6.2.0-18.18 -proposed tracker (LP: #2011750) + + * lunar/linux 6.2 fails to boot on arm64 (LP: #2011748) + - SAUCE: Revert "efi: random: fix NULL-deref when refreshing seed" + - SAUCE: Revert "efi: random: refresh non-volatile random seed when RNG is + initialized" + + -- Andrea Righi Wed, 15 Mar 2023 23:54:18 +0100 + +linux (6.2.0-17.17) lunar; urgency=medium + + * lunar/linux: 6.2.0-17.17 -proposed tracker (LP: #2011593) + + * lunar/linux 6.2 fails to boot on ppc64el (LP: #2011413) + - SAUCE: Revert "powerpc: remove STACK_FRAME_OVERHEAD" + - SAUCE: Revert "powerpc/pseries: hvcall stack frame overhead" + + * Speaker / Audio/Mic mute LED don't work on a HP platform (LP: #2011379) + - SAUCE: ALSA: hda/realtek: fix speaker, mute/micmute LEDs not work on a HP + platform + + * Some QHD panels fail to refresh when PSR2 enabled (LP: #2009014) + - SAUCE: drm/i915/psr: Use calculated io and fast wake lines + + * Lunar update: v6.2.6 upstream stable release (LP: #2011431) + - tpm: disable hwrng for fTPM on some AMD designs + - wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext" + - staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script + - staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh + - Linux 6.2.6 + + * Lunar update: v6.2.5 upstream stable release (LP: #2011430) + - net/sched: Retire tcindex classifier + - auxdisplay: hd44780: Fix potential memory leak in hd44780_remove() + - fs/jfs: fix shift exponent db_agl2size negative + - driver: soc: xilinx: fix memory leak in xlnx_add_cb_for_notify_event() + - f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin + - f2fs: fix to avoid potential deadlock + - objtool: Fix memory leak in create_static_call_sections() + - soc: mediatek: mtk-pm-domains: Allow mt8186 ADSP default power on + - soc: qcom: socinfo: Fix soc_id order + - memory: renesas-rpc-if: Split-off private data from struct rpcif + - memory: renesas-rpc-if: Move resource acquisition to .probe() + - soc: mediatek: mtk-svs: Enable the IRQ later + - pwm: sifive: Always let the first pwm_apply_state succeed + - pwm: stm32-lp: fix the check on arr and cmp registers update + - f2fs: introduce trace_f2fs_replace_atomic_write_block + - f2fs: clear atomic_write_task in f2fs_abort_atomic_write() + - soc: mediatek: mtk-svs: restore default voltages when svs_init02() fail + - soc: mediatek: mtk-svs: reset svs when svs_resume() fail + - soc: mediatek: mtk-svs: Use pm_runtime_resume_and_get() in svs_init01() + - f2fs: fix to do sanity check on extent cache correctly + - fs: f2fs: initialize fsdata in pagecache_write() + - f2fs: allow set compression option of files without blocks + - f2fs: fix to abort atomic write only during do_exist() + - um: vector: Fix memory leak in vector_config + - ubi: ensure that VID header offset + VID header size <= alloc, size + - ubifs: Fix build errors as symbol undefined + - ubifs: Fix memory leak in ubifs_sysfs_init() + - ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted + - ubifs: Rectify space budget for ubifs_xrename() + - ubifs: Fix wrong dirty space budget for dirty inode + - ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1 + - ubifs: Reserve one leb for each journal head while doing budget + - ubi: Fix use-after-free when volume resizing failed + - ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume() + - ubifs: Fix memory leak in alloc_wbufs() + - ubi: Fix possible null-ptr-deref in ubi_free_volume() + - ubifs: Re-statistic cleaned znode count if commit failed + - ubifs: dirty_cow_znode: Fix memleak in error handling path + - ubifs: ubifs_writepage: Mark page dirty after writing inode failed + - ubifs: ubifs_releasepage: Remove ubifs_assert(0) to valid this process + - ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling + fastmap + - ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show() + - ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed + - f2fs: fix to handle F2FS_IOC_START_ATOMIC_REPLACE in f2fs_compat_ioctl() + - f2fs: fix to avoid potential memory corruption in __update_iostat_latency() + - f2fs: fix to update age extent correctly during truncation + - f2fs: fix to update age extent in f2fs_do_zero_range() + - soc: qcom: stats: Populate all subsystem debugfs files + - f2fs: introduce IS_F2FS_IPU_* macro + - f2fs: fix to set ipu policy + - ext4: use ext4_fc_tl_mem in fast-commit replay path + - ext4: don't show commit interval if it is zero + - netfilter: nf_tables: allow to fetch set elements when table has an owner + - x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list + - um: virtio_uml: free command if adding to virtqueue failed + - um: virtio_uml: mark device as unregistered when breaking it + - um: virtio_uml: move device breaking into workqueue + - um: virt-pci: properly remove PCI device from bus + - f2fs: synchronize atomic write aborts + - watchdog: rzg2l_wdt: Issue a reset before we put the PM clocks + - watchdog: rzg2l_wdt: Handle TYPE-B reset for RZ/V2M + - watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in + error path + - watchdog: Fix kmemleak in watchdog_cdev_register + - watchdog: pcwd_usb: Fix attempting to access uninitialized memory + - watchdog: sbsa_wdog: Make sure the timeout programming is within the limits + - netfilter: ctnetlink: fix possible refcount leak in + ctnetlink_create_conntrack() + - netfilter: conntrack: fix rmmod double-free race + - netfilter: ip6t_rpfilter: Fix regression with VRF interfaces + - netfilter: ebtables: fix table blob use-after-free + - netfilter: xt_length: use skb len to match in length_mt6 + - netfilter: ctnetlink: make event listener tracking global + - netfilter: x_tables: fix percpu counter block leak on error path when + creating new netns + - swiotlb: mark swiotlb_memblock_alloc() as __init + - ptp: vclock: use mutex to fix "sleep on atomic" bug + - drm/i915: move a Kconfig symbol to unbreak the menu presentation + - ipv6: Add lwtunnel encap size of all siblings in nexthop calculation + - drm/i915/xelpmp: Consider GSI offset when doing MCR lookups + - octeontx2-pf: Recalculate UDP checksum for ptp 1-step sync packet + - net: sunhme: Fix region request + - sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop + - octeontx2-pf: Use correct struct reference in test condition + - net: fix __dev_kfree_skb_any() vs drop monitor + - 9p/xen: fix version parsing + - 9p/xen: fix connection sequence + - 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv() + - spi: tegra210-quad: Fix validate combined sequence + - mlx5: fix skb leak while fifo resync and push + - mlx5: fix possible ptp queue fifo use-after-free + - net/mlx5: ECPF, wait for VF pages only after disabling host PFs + - net/mlx5e: Verify flow_source cap before using it + - net/mlx5: Geneve, Fix handling of Geneve object id as error code + - ext4: fix incorrect options show of original mount_opt and extend mount_opt2 + - nfc: fix memory leak of se_io context in nfc_genl_se_io + - net/sched: transition act_pedit to rcu and percpu stats + - net/sched: act_pedit: fix action bind logic + - net/sched: act_mpls: fix action bind logic + - net/sched: act_sample: fix action bind logic + - net: dsa: seville: ignore mscc-miim read errors from Lynx PCS + - net: dsa: felix: fix internal MDIO controller resource length + - ARM: dts: aspeed: p10bmc: Update battery node name + - ARM: dts: spear320-hmi: correct STMPE GPIO compatible + - tcp: tcp_check_req() can be called from process context + - vc_screen: modify vcs_size() handling in vcs_read() + - spi: tegra210-quad: Fix iterator outside loop + - rtc: sun6i: Always export the internal oscillator + - genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask() + - scsi: ipr: Work around fortify-string warning + - scsi: mpi3mr: Fix an issue found by KASAN + - scsi: mpi3mr: Use number of bits to manage bitmap sizes + - rtc: allow rtc_read_alarm without read_alarm callback + - io_uring: fix size calculation when registering buf ring + - loop: loop_set_status_from_info() check before assignment + - ASoC: adau7118: don't disable regulators on device unbind + - ASoC: apple: mca: Fix final status read on SERDES reset + - ASoC: apple: mca: Fix SERDES reset sequence + - ASoC: apple: mca: Improve handling of unavailable DMA channels + - nvme: bring back auto-removal of deleted namespaces during sequential scan + - nvme-tcp: don't access released socket during error recovery + - nvme-fabrics: show well known discovery name + - ASoC: zl38060 add gpiolib dependency + - ASoC: mediatek: mt8195: add missing initialization + - thermal: intel: quark_dts: fix error pointer dereference + - thermal: intel: BXT_PMIC: select REGMAP instead of depending on it + - cpufreq: apple-soc: Fix an IS_ERR() vs NULL check + - tracing: Add NULL checks for buffer in ring_buffer_free_read_page() + - kernel/printk/index.c: fix memory leak with using debugfs_lookup() + - firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3 + - bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC + support + - mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak + - IB/hfi1: Update RMT size calculation + - iommu: Remove deferred attach check from __iommu_detach_device() + - PCI/ACPI: Account for _S0W of the target bridge in acpi_pci_bridge_d3() + - media: uvcvideo: Remove format descriptions + - media: uvcvideo: Handle cameras with invalid descriptors + - media: uvcvideo: Handle errors from calls to usb_string + - media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910 + - media: uvcvideo: Silence memcpy() run-time false positive warnings + - USB: fix memory leak with using debugfs_lookup() + - cacheinfo: Fix shared_cpu_map to handle shared caches at different levels + - usb: fotg210: List different variants + - dt-bindings: usb: Add device id for Genesys Logic hub controller + - staging: emxx_udc: Add checks for dma_alloc_coherent() + - tty: fix out-of-bounds access in tty_driver_lookup_tty() + - tty: serial: fsl_lpuart: disable the CTS when send break signal + - serial: sc16is7xx: setup GPIO controller later in probe + - mei: bus-fixup:upon error print return values of send and receive + - tools/iio/iio_utils:fix memory leak + - bus: mhi: ep: Fix the debug message for MHI_PKT_TYPE_RESET_CHAN_CMD cmd + - iio: accel: mma9551_core: Prevent uninitialized variable in + mma9551_read_status_word() + - iio: accel: mma9551_core: Prevent uninitialized variable in + mma9551_read_config_word() + - media: uvcvideo: Add GUID for BGRA/X 8:8:8:8 + - soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe() + - PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown + - PCI: loongson: Prevent LS7A MRRS increases + - staging: pi433: fix memory leak with using debugfs_lookup() + - USB: dwc3: fix memory leak with using debugfs_lookup() + - USB: chipidea: fix memory leak with using debugfs_lookup() + - USB: ULPI: fix memory leak with using debugfs_lookup() + - USB: uhci: fix memory leak with using debugfs_lookup() + - USB: sl811: fix memory leak with using debugfs_lookup() + - USB: fotg210: fix memory leak with using debugfs_lookup() + - USB: isp116x: fix memory leak with using debugfs_lookup() + - USB: isp1362: fix memory leak with using debugfs_lookup() + - USB: gadget: gr_udc: fix memory leak with using debugfs_lookup() + - USB: gadget: bcm63xx_udc: fix memory leak with using debugfs_lookup() + - USB: gadget: lpc32xx_udc: fix memory leak with using debugfs_lookup() + - USB: gadget: pxa25x_udc: fix memory leak with using debugfs_lookup() + - USB: gadget: pxa27x_udc: fix memory leak with using debugfs_lookup() + - usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer + math + - USB: ene_usb6250: Allocate enough memory for full object + - usb: uvc: Enumerate valid values for color matching + - usb: gadget: uvc: Make bSourceID read/write + - PCI: Align extra resources for hotplug bridges properly + - PCI: Take other bus devices into account when distributing resources + - PCI: Distribute available resources for root buses, too + - tty: pcn_uart: fix memory leak with using debugfs_lookup() + - misc: vmw_balloon: fix memory leak with using debugfs_lookup() + - drivers: base: component: fix memory leak with using debugfs_lookup() + - drivers: base: dd: fix memory leak with using debugfs_lookup() + - kernel/fail_function: fix memory leak with using debugfs_lookup() + - PCI: loongson: Add more devices that need MRRS quirk + - PCI: Add ACS quirk for Wangxun NICs + - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum + - phy: rockchip-typec: Fix unsigned comparison with less than zero + - RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size + - soundwire: cadence: Remove wasted space in response_buf + - soundwire: cadence: Drain the RX FIFO after an IO timeout + - eth: fealnx: bring back this old driver + - net: tls: avoid hanging tasks on the tx_lock + - x86/resctl: fix scheduler confusion with 'current' + - vDPA/ifcvf: decouple hw features manipulators from the adapter + - vDPA/ifcvf: decouple config space ops from the adapter + - vDPA/ifcvf: alloc the mgmt_dev before the adapter + - vDPA/ifcvf: decouple vq IRQ releasers from the adapter + - vDPA/ifcvf: decouple config IRQ releaser from the adapter + - vDPA/ifcvf: decouple vq irq requester from the adapter + - vDPA/ifcvf: decouple config/dev IRQ requester and vectors allocator from the + adapter + - vDPA/ifcvf: ifcvf_request_irq works on ifcvf_hw + - vDPA/ifcvf: manage ifcvf_hw in the mgmt_dev + - vDPA/ifcvf: allocate the adapter in dev_add() + - drm/display/dp_mst: Add drm_atomic_get_old_mst_topology_state() + - drm/display/dp_mst: Fix down/up message handling after sink disconnect + - drm/display/dp_mst: Fix down message handling after a packet reception error + - drm/display/dp_mst: Fix payload addition on a disconnected sink + - drm/i915/dp_mst: Add the MST topology state for modesetted CRTCs + - drm/display/dp_mst: Handle old/new payload states in drm_dp_remove_payload() + - drm/i915/dp_mst: Fix payload removal during output disabling + - drm/i915: Fix system suspend without fbdev being initialized + - media: uvcvideo: Fix race condition with usb_kill_urb + - arm64: efi: Make efi_rt_lock a raw_spinlock + - usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails + - Linux 6.2.5 + + * Lunar update: v6.2.4 upstream stable release (LP: #2011428) + - Revert "blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and + blkcg_deactivate_policy()" + - Revert "blk-cgroup: dropping parent refcount after pd_free_fn() is done" + - Linux 6.2.4 + + * Lunar update: v6.2.3 upstream stable release (LP: #2011425) + - HID: asus: use spinlock to protect concurrent accesses + - HID: asus: use spinlock to safely schedule workers + - iommu/amd: Fix error handling for pdev_pri_ats_enable() + - iommu/amd: Skip attach device domain is same as new domain + - iommu/amd: Improve page fault error reporting + - iommu: Attach device group to old domain in error path + - powerpc/mm: Rearrange if-else block to avoid clang warning + - ata: ahci: Revert "ata: ahci: Add Tiger Lake UP{3,4} AHCI controller" + - ARM: OMAP2+: Fix memory leak in realtime_counter_init() + - arm64: dts: qcom: qcs404: use symbol names for PCIe resets + - arm64: dts: qcom: msm8996-tone: Fix USB taking 6 minutes to wake up + - arm64: dts: qcom: sm6115: Fix UFS node + - arm64: dts: qcom: sm6115: Provide xo clk to rpmcc + - arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k + - arm64: dts: qcom: pmi8950: Correct rev_1250v channel label to mv + - arm64: dts: qcom: sm6350: Fix up the ramoops node + - arm64: dts: qcom: sdm670-google-sargo: keep pm660 ldo8 on + - arm64: dts: qcom: Re-enable resin on MSM8998 and SDM845 boards + - arm64: dts: qcom: sm8350-sagami: Configure SLG51000 PMIC on PDX215 + - arm64: dts: qcom: sm8350-sagami: Add GPIO line names for PMIC GPIOs + - arm64: dts: qcom: sm8350-sagami: Rectify GPIO keys + - arm64: dts: qcom: sm6350-lena: Flatten gpio-keys pinctrl state + - arm64: dts: qcom: sm6125: Reorder HSUSB PHY clocks to match bindings + - arm64: dts: qcom: sm6125-seine: Clean up gpio-keys (volume down) + - arm64: dts: imx8m: Align SoC unique ID node unit address + - ARM: zynq: Fix refcount leak in zynq_early_slcr_init + - fs: dlm: fix return value check in dlm_memory_init() + - arm64: dts: mediatek: mt8195: Add power domain to U3PHY1 T-PHY + - arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description + - arm64: dts: mediatek: mt8192: Fix systimer 13 MHz clock description + - arm64: dts: mediatek: mt8195: Fix systimer 13 MHz clock description + - arm64: dts: mediatek: mt8186: Fix systimer 13 MHz clock description + - arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name + - arm64: dts: qcom: sdm845-xiaomi-beryllium: fix audio codec interrupt pin + name + - x86/acpi/boot: Do not register processors that cannot be onlined for x2APIC + - arm64: dts: qcom: sc7180: correct SPMI bus address cells + - arm64: dts: qcom: sc7280: correct SPMI bus address cells + - arm64: dts: qcom: sc8280xp: correct SPMI bus address cells + - arm64: dts: qcom: sm8450: correct Soundwire wakeup interrupt name + - arm64: dts: qcom: sdm845: make DP node follow the schema + - arm64: dts: qcom: msm8996-oneplus-common: drop vdda-supply from DSI PHY + - arm64: dts: qcom: sc8280xp: Vote for CX in USB controllers + - arm64: dts: meson-gxl: jethub-j80: Fix WiFi MAC address node + - arm64: dts: meson-gxl: jethub-j80: Fix Bluetooth MAC node name + - arm64: dts: meson-axg: jethub-j1xx: Fix MAC address node names + - arm64: dts: meson-gx: Fix Ethernet MAC address unit name + - arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name + - arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address + - cpuidle, intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE *again* + - arm64: dts: ti: k3-am62-main: Fix clocks for McSPI + - arm64: tegra: Fix duplicate regulator on Jetson TX1 + - arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem size + - arm64: dts: qcom: msm8992-bullhead: Disable dfps_data_mem + - arm64: dts: qcom: msm8956: use SoC-specific compat for tsens + - arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names + - arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY + - arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY + - arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges + - arm64: dts: qcom: ipq8074: fix Gen3 PCIe node + - arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names + - arm64: dts: meson: remove CPU opps below 1GHz for G12A boards + - ARM: OMAP1: call platform_device_put() in error case in + omap1_dm_timer_init() + - arm64: dts: mediatek: mt8192: Mark scp_adsp clock as broken + - ARM: bcm2835_defconfig: Enable the framebuffer + - ARM: s3c: fix s3c64xx_set_timer_source prototype + - arm64: dts: ti: k3-j7200: Fix wakeup pinmux range + - ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato + - ARM: imx: Call ida_simple_remove() for ida_simple_get + - arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name + - arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name + - arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible + - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix supply name of USB + controller node + - arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names + property + - arm64: dts: amlogic: meson-gx: add missing unit address to rng node name + - arm64: dts: amlogic: meson-gxl-s905w-jethome-jethub-j80: fix invalid rtc + node name + - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix invalid rtc node + name + - arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node + name + - arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name + - arm64: dts: amlogic: meson-sm1-bananapi-m5: fix adc keys node names + - arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name + - arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name + - arm64: dts: amlogic: meson-g12b-odroid-go-ultra: fix rk818 pmic properties + - arm64: dts: amlogic: meson-sm1-odroid-hc4: fix active fan thermal trip + - locking/rwsem: Disable preemption in all down_read*() and up_read() code + paths + - arm64: tegra: Mark host1x as dma-coherent on Tegra194/234 + - arm64: dts: renesas: beacon-renesom: Fix gpio expander reference + - arm64: dts: meson: radxa-zero: allow usb otg mode + - arm64: dts: meson: bananapi-m5: switch VDDIO_C pin to OPEN_DRAIN + - ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference + - ublk_drv: remove nr_aborted_queues from ublk_device + - ublk_drv: don't probe partitions if the ubq daemon isn't trusted + - ARM: dts: imx7s: correct iomuxc gpr mux controller cells + - sbitmap: remove redundant check in __sbitmap_queue_get_batch + - sbitmap: correct wake_batch recalculation to avoid potential IO hung + - arm64: dts: mt8195: Fix CPU map for single-cluster SoC + - arm64: dts: mt8192: Fix CPU map for single-cluster SoC + - arm64: dts: mt8186: Fix CPU map for single-cluster SoC + - arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node + - arm64: dts: mediatek: mt8186: Fix watchdog compatible + - arm64: dts: mediatek: mt8195: Fix watchdog compatible + - arm64: dts: mediatek: mt7986: Fix watchdog compatible + - ARM: dts: stm32: Update part number NVMEM description on stm32mp131 + - arm64: dts: qcom: sm8450-nagara: Correct firmware paths + - blk-mq: avoid sleep in blk_mq_alloc_request_hctx + - blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx + - blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait + - blk-mq: Fix potential io hung for shared sbitmap per tagset + - blk-mq: correct stale comment of .get_budget + - arm64: dts: qcom: msm8996: support using GPLL0 as kryocc input + - arm64: dts: qcom: msm8996 switch from RPM_SMD_BB_CLK1 to RPM_SMD_XO_CLK_SRC + - arm64: dts: qcom: sm8350: drop incorrect cells from serial + - arm64: dts: qcom: sm8450: drop incorrect cells from serial + - arm64: dts: qcom: msm8992-lg-bullhead: Correct memory overlaps with the SMEM + and MPSS memory regions + - arm64: dts: qcom: msm8953: correct TLMM gpio-ranges + - arm64: dts: qcom: sm6115: correct TLMM gpio-ranges + - arm64: dts: qcom: msm8992-lg-bullhead: Enable regulators + - s390/dasd: Fix potential memleak in dasd_eckd_init() + - io_uring,audit: don't log IORING_OP_MADVISE + - sched/rt: pick_next_rt_entity(): check list_entry + - perf/x86/intel/ds: Fix the conversion from TSC to perf time + - x86/perf/zhaoxin: Add stepping check for ZXC + - KEYS: asymmetric: Fix ECDSA use via keyctl uapi + - block: ublk: check IO buffer based on flag need_get_data + - arm64: dts: qcom: pmk8350: Use the correct PON compatible + - erofs: relinquish volume with mutex held + - block: sync mixed merged request's failfast with 1st bio's + - block: Fix io statistics for cgroup in throttle path + - block: bio-integrity: Copy flags when bio_integrity_payload is cloned + - block: use proper return value from bio_failfast() + - wifi: mt76: mt7915: add missing of_node_put() + - wifi: mt76: mt7921s: fix slab-out-of-bounds access in sdio host + - wifi: mt76: mt7915: fix mt7915_rate_txpower_get() resource leaks + - wifi: mt76: mt7996: fix insecure data handling of mt7996_mcu_ie_countdown() + - wifi: mt76: mt7996: fix insecure data handling of + mt7996_mcu_rx_radar_detected() + - wifi: mt76: mt7996: fix integer handling issue of mt7996_rf_regval_set() + - wifi: mt76: mt7915: check return value before accessing free_block_num + - wifi: mt76: mt7996: check return value before accessing free_block_num + - wifi: mt76: mt7915: drop always true condition of __mt7915_reg_addr() + - wifi: mt76: mt7996: drop always true condition of __mt7996_reg_addr() + - wifi: mt76: mt7996: fix endianness warning in mt7996_mcu_sta_he_tlv + - wifi: mt76: mt76x0: fix oob access in mt76x0_phy_get_target_power + - wifi: mt76: mt7996: fix unintended sign extension of mt7996_hw_queue_read() + - wifi: mt76: mt7915: fix unintended sign extension of mt7915_hw_queue_read() + - wifi: mt76: fix coverity uninit_use_in_call in + mt76_connac2_reverse_frag0_hdr_trans() + - wifi: mt76: mt7921: resource leaks at mt7921_check_offload_capability() + - wifi: rsi: Fix memory leak in rsi_coex_attach() + - wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave() + - wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave() + - wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave() + - wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: libertas: fix memory leak in lbs_init_adapter() + - wifi: rtl8xxxu: Fix assignment to bit field priv->pi_enabled + - wifi: rtl8xxxu: Fix assignment to bit field priv->cck_agc_report_type + - wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: rtw89: 8852c: rfk: correct DACK setting + - wifi: rtw89: 8852c: rfk: correct DPK settings + - wifi: rtlwifi: Fix global-out-of-bounds bug in + _rtl8812ae_phy_set_txpower_limit() + - libbpf: Fix single-line struct definition output in btf_dump + - libbpf: Fix btf__align_of() by taking into account field offsets + - wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: ipw2200: fix memory leak in ipw_wdev_init() + - wifi: wilc1000: fix potential memory leak in wilc_mac_xmit() + - wifi: wilc1000: add missing unregister_netdev() in wilc_netdev_ifc_init() + - wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit() + - wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid() + - wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave() + - wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave() + - libbpf: Fix invalid return address register in s390 + - crypto: x86/ghash - fix unaligned access in ghash_setkey() + - crypto: ux500 - update debug config after ux500 cryp driver removal + - ACPICA: Drop port I/O validation for some regions + - genirq: Fix the return type of kstat_cpu_irqs_sum() + - rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose + - rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls + - rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes() + - lib/mpi: Fix buffer overrun when SG is too long + - crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2 + - platform/chrome: cros_ec_typec: Update port DP VDO + - ACPICA: nsrepair: handle cases without a return value correctly + - libbpf: Fix map creation flags sanitization + - bpf_doc: Fix build error with older python versions + - selftests/xsk: print correct payload for packet dump + - selftests/xsk: print correct error codes when exiting + - arm64/cpufeature: Fix field sign for DIT hwcap detection + - arm64/sysreg: Fix errors in 32 bit enumeration values + - kselftest/arm64: Fix syscall-abi for systems without 128 bit SME + - workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex + - s390/early: fix sclp_early_sccb variable lifetime + - s390/vfio-ap: fix an error handling path in vfio_ap_mdev_probe_queue() + - x86/signal: Fix the value returned by strict_sas_size() + - thermal/drivers/tsens: Drop msm8976-specific defines + - thermal/drivers/tsens: Sort out msm8976 vs msm8956 data + - thermal/drivers/tsens: fix slope values for msm8939 + - thermal/drivers/tsens: limit num_sensors to 9 for msm8939 + - wifi: rtw89: fix potential leak in rtw89_append_probe_req_ie() + - wifi: rtw89: Add missing check for alloc_workqueue + - wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU + - wifi: orinoco: check return value of hermes_write_wordrec() + - wifi: rtw88: Use rtw_iterate_vifs() for rtw_vif_watch_dog_iter() + - wifi: rtw88: Use non-atomic sta iterator in rtw_ra_mask_info_update() + - thermal/drivers/imx_sc_thermal: Fix the loop condition + - wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback + function + - wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails + - wifi: ath9k: Fix potential stack-out-of-bounds write in + ath9k_wmi_rsp_callback() + - wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup + - wifi: cfg80211: Fix extended KCK key length check in + nl80211_set_rekey_data() + - ACPI: battery: Fix missing NUL-termination with large strings + - selftests/bpf: Fix build errors if CONFIG_NF_CONNTRACK=m + - crypto: ccp - Failure on re-initialization due to duplicate sysfs filename + - crypto: essiv - Handle EBUSY correctly + - crypto: seqiv - Handle EBUSY correctly + - powercap: fix possible name leak in powercap_register_zone() + - bpf: Fix state pruning for STACK_DYNPTR stack slots + - bpf: Fix missing var_off check for ARG_PTR_TO_DYNPTR + - bpf: Fix partial dynptr stack slot reads/writes + - x86/microcode: Add a parameter to microcode_check() to store CPU + capabilities + - x86/microcode: Check CPU capabilities after late microcode update correctly + - x86/microcode: Adjust late loading result reporting message + - net: ethernet: ti: am65-cpsw/cpts: Fix CPTS release action + - selftests/bpf: Fix vmtest static compilation error + - crypto: xts - Handle EBUSY correctly + - leds: led-class: Add missing put_device() to led_put() + - drm/nouveau/disp: Fix nvif_outp_acquire_dp() argument size + - s390/bpf: Add expoline to tail calls + - wifi: iwlwifi: mei: fix compilation errors in rfkill() + - kselftest/arm64: Fix enumeration of systems without 128 bit SME + - can: rcar_canfd: Fix R-Car V3U CAN mode selection + - can: rcar_canfd: Fix R-Car V3U GAFLCFG field accesses + - selftests/bpf: Initialize tc in xdp_synproxy + - crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware + - bpftool: profile online CPUs instead of possible + - wifi: mt76: mt7921: fix deadlock in mt7921_abort_roc + - wifi: mt76: mt7915: call mt7915_mcu_set_thermal_throttling() only after + init_work + - wifi: mt76: mt7915: rework mt7915_mcu_set_thermal_throttling + - wifi: mt76: mt7915: rework mt7915_thermal_temp_store() + - wifi: mt76: mt7921: fix channel switch fail in monitor mode + - wifi: mt76: mt7996: fix chainmask calculation in mt7996_set_antenna() + - wifi: mt76: mt7996: update register for CFEND_RATE + - wifi: mt76: connac: fix POWER_CTRL command name typo + - wifi: mt76: mt7921: fix invalid remain_on_channel duration + - wifi: mt76: mt7915: fix memory leak in mt7915_mcu_exit + - wifi: mt76: mt7996: fix memory leak in mt7996_mcu_exit + - wifi: mt76: dma: fix memory leak running mt76_dma_tx_cleanup + - wifi: mt76: fix switch default case in mt7996_reverse_frag0_hdr_trans + - wifi: mt76: mt7915: fix WED TxS reporting + - wifi: mt76: add memory barrier to SDIO queue kick + - wifi: mt76: mt7996: rely on mt76_connac2_mac_tx_rate_val + - net/mlx5: Enhance debug print in page allocation failure + - irqchip: Fix refcount leak in platform_irqchip_probe + - irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains + - irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe + - irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe + - s390/mem_detect: fix detect_memory() error handling + - s390/vmem: fix empty page tables cleanup under KASAN + - s390/boot: cleanup decompressor header files + - s390/mem_detect: rely on diag260() if sclp_early_get_memsize() fails + - s390/boot: fix mem_detect extended area allocation + - net: add sock_init_data_uid() + - tun: tun_chr_open(): correctly initialize socket uid + - tap: tap_open(): correctly initialize socket uid + - rxrpc: Fix overwaking on call poking + - OPP: fix error checking in opp_migrate_dentry() + - cpufreq: davinci: Fix clk use after free + - Bluetooth: hci_conn: Refactor hci_bind_bis() since it always succeeds + - Bluetooth: L2CAP: Fix potential user-after-free + - Bluetooth: hci_qca: get wakeup status from serdev device handle + - net: ipa: generic command param fix + - s390: vfio-ap: tighten the NIB validity check + - s390/ap: fix status returned by ap_aqic() + - s390/ap: fix status returned by ap_qact() + - libbpf: Fix alen calculation in libbpf_nla_dump_errormsg() + - xen/grant-dma-iommu: Implement a dummy probe_device() callback + - rds: rds_rm_zerocopy_callback() correct order for list_add_tail() + - crypto: rsa-pkcs1pad - Use akcipher_request_complete + - m68k: /proc/hardware should depend on PROC_FS + - RISC-V: time: initialize hrtimer based broadcast clock event device + - clocksource/drivers/riscv: Patch riscv_clock_next_event() jump before first + use + - wifi: iwl3945: Add missing check for create_singlethread_workqueue + - wifi: iwl4965: Add missing check for create_singlethread_workqueue() + - wifi: brcmfmac: Rename Cypress 89459 to BCM4355 + - wifi: brcmfmac: pcie: Add IDs/properties for BCM4355 + - wifi: brcmfmac: pcie: Add IDs/properties for BCM4377 + - wifi: brcmfmac: pcie: Perform correct BCM4364 firmware selection + - wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize() + - wifi: rtw89: fix parsing offset for MCC C2H + - selftests/bpf: Fix out-of-srctree build + - ACPI: resource: Add IRQ overrides for MAINGEAR Vector Pro 2 models + - ACPI: resource: Do IRQ override on all TongFang GMxRGxx + - crypto: octeontx2 - Fix objects shared between several modules + - crypto: crypto4xx - Call dma_unmap_page when done + - vfio/ccw: remove WARN_ON during shutdown + - wifi: mac80211: move color collision detection report in a delayed work + - wifi: mac80211: make rate u32 in sta_set_rate_info_rx() + - wifi: mac80211: fix non-MLO station association + - wifi: mac80211: Don't translate MLD addresses for multicast + - wifi: mac80211: avoid u32_encode_bits() warning + - wifi: mac80211: fix off-by-one link setting + - tools/lib/thermal: Fix thermal_sampling_exit() + - thermal/drivers/hisi: Drop second sensor hi3660 + - selftests/bpf: Fix map_kptr test. + - wifi: mac80211: pass 'sta' to ieee80211_rx_data_set_sta() + - bpf: Zeroing allocated object from slab in bpf memory allocator + - selftests/bpf: Fix xdp_do_redirect on s390x + - can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a + bus error + - can: esd_usb: Make use of can_change_state() and relocate checking skb for + NULL + - xsk: check IFF_UP earlier in Tx path + - LoongArch, bpf: Use 4 instructions for function address in JIT + - bpf: Fix global subprog context argument resolution logic + - irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts + - irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts + - net/smc: fix potential panic dues to unprotected smc_llc_srv_add_link() + - net/smc: fix application data exception + - selftests/net: Interpret UDP_GRO cmsg data as an int value + - l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register() + - net: bcmgenet: fix MoCA LED control + - net: lan966x: Fix possible deadlock inside PTP + - net/mlx4_en: Introduce flexible array to silence overflow warning + - net/mlx5e: Align IPsec ASO result memory to be as required by hardware + - selftest: fib_tests: Always cleanup before exit + - sefltests: netdevsim: wait for devlink instance after netns removal + - drm: Fix potential null-ptr-deref due to drmm_mode_config_init() + - drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats + - drm/bridge: ti-sn65dsi83: Fix delay after reset deassert to match spec + - drm: mxsfb: DRM_IMX_LCDIF should depend on ARCH_MXC + - drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC + - drm/bridge: megachips: Fix error handling in i2c_register_driver() + - drm/vkms: Fix memory leak in vkms_init() + - drm/vkms: Fix null-ptr-deref in vkms_release() + - drm/modes: Use strscpy() to copy command-line mode name + - drm/vc4: dpi: Fix format mapping for RGB565 + - drm/bridge: it6505: Guard bridge power in IRQ handler + - drm: tidss: Fix pixel format definition + - gpu: ipu-v3: common: Add of_node_put() for reference returned by + of_graph_get_port_by_id() + - drm/ast: Init iosys_map pointer as I/O memory for damage handling + - drm/vc4: drop all currently held locks if deadlock happens + - hwmon: (ftsteutates) Fix scaling of measurements + - drm/msm/dpu: check for null return of devm_kzalloc() in dpu_writeback_init() + - drm/msm/hdmi: Add missing check for alloc_ordered_workqueue + - pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins + - pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain + - pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups + - drm/vc4: hvs: Configure the HVS COB allocations + - drm/vc4: hvs: Set AXI panic modes + - drm/vc4: hvs: SCALER_DISPBKGND_AUTOHS is only valid on HVS4 + - drm/vc4: hvs: Correct interrupt masking bit assignment for HVS5 + - drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5 + - drm/vc4: hdmi: Correct interlaced timings again + - drm/msm: clean event_thread->worker in case of an error + - drm/panel-edp: fix name for IVO product id 854b + - scsi: qla2xxx: Fix exchange oversubscription + - scsi: qla2xxx: Fix exchange oversubscription for management commands + - scsi: qla2xxx: edif: Fix clang warning + - ASoC: fsl_sai: initialize is_dsp_mode flag + - drm/bridge: tc358767: Set default CLRSIPO count + - drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup() + - ALSA: hda/ca0132: minor fix for allocation size + - drm/amdgpu: Use the sched from entity for amdgpu_cs trace + - drm/msm/gem: Add check for kmalloc + - drm/msm/dpu: Disallow unallocated resources to be returned + - drm/bridge: lt9611: fix sleep mode setup + - drm/bridge: lt9611: fix HPD reenablement + - drm/bridge: lt9611: fix polarity programming + - drm/bridge: lt9611: fix programming of video modes + - drm/bridge: lt9611: fix clock calculation + - drm/bridge: lt9611: pass a pointer to the of node + - regulator: tps65219: use IS_ERR() to detect an error pointer + - drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness + - drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags + - drm/msm/dsi: Allow 2 CTRLs on v2.5.0 + - scsi: ufs: exynos: Fix DMA alignment for PAGE_SIZE != 4096 + - drm/msm/dpu: sc7180: add missing WB2 clock control + - drm/msm: use strscpy instead of strncpy + - drm/msm/dpu: Add check for cstate + - drm/msm/dpu: Add check for pstates + - drm/msm/mdp5: Add check for kzalloc + - habanalabs: bugs fixes in timestamps buff alloc + - pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback() + - pinctrl: mediatek: Initialize variable pullen and pullup to zero + - pinctrl: mediatek: Initialize variable *buf to zero + - gpu: host1x: Fix mask for syncpoint increment register + - gpu: host1x: Don't skip assigning syncpoints to channels + - drm/tegra: firewall: Check for is_addr_reg existence in IMM check + - drm/i915/mtl: Add initial gt workarounds + - drm/i915/xehp: GAM registers don't need to be re-applied on engine resets + - pinctrl: renesas: rzg2l: Fix configuring the GPIO pins as interrupts + - drm/i915/xehp: Annotate a couple more workaround registers as MCR + - drm/msm/dpu: set pdpu->is_rt_pipe early in dpu_plane_sspp_atomic_update() + - drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd + - drm/mediatek: Use NULL instead of 0 for NULL pointer + - drm/mediatek: Drop unbalanced obj unref + - drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc + - drm/mediatek: Clean dangling pointer on bind error path + - ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress() + - dt-bindings: display: mediatek: Fix the fallback for mediatek,mt8186-disp- + ccorr + - gpio: pca9570: rename platform_data to chip_data + - gpio: vf610: connect GPIO label to dev name + - ASoC: topology: Properly access value coming from topology file + - spi: dw_bt1: fix MUX_MMIO dependencies + - ASoC: mchp-spdifrx: fix controls which rely on rsr register + - ASoC: mchp-spdifrx: fix return value in case completion times out + - ASoC: mchp-spdifrx: fix controls that works with completion mechanism + - ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove() + - dm: improve shrinker debug names + - regmap: apply reg_base and reg_downshift for single register ops + - accel: fix CONFIG_DRM dependencies + - ASoC: rsnd: fixup #endif position + - ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params() + - ASoC: dt-bindings: meson: fix gx-card codec node regex + - regulator: tps65219: use generic set_bypass() + - hwmon: (asus-ec-sensors) add missing mutex path + - hwmon: (ltc2945) Handle error case in ltc2945_value_store + - ALSA: hda: Fix the control element identification for multiple codecs + - drm/amdgpu: fix enum odm_combine_mode mismatch + - scsi: mpt3sas: Fix a memory leak + - scsi: aic94xx: Add missing check for dma_map_single() + - HID: multitouch: Add quirks for flipped axes + - HID: retain initial quirks set up when creating HID devices + - ASoC: qcom: q6apm-lpass-dai: unprepare stream if its already prepared + - ASoC: qcom: q6apm-dai: fix race condition while updating the position + pointer + - ASoC: qcom: q6apm-dai: Add SNDRV_PCM_INFO_BATCH flag + - ASoC: codecs: lpass: register mclk after runtime pm + - ASoC: codecs: lpass: fix incorrect mclk rate + - drm/amd/display: don't call dc_interrupt_set() for disabled crtcs + - HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support + - spi: bcm63xx-hsspi: Fix multi-bit mode setting + - hwmon: (mlxreg-fan) Return zero speed for broken fan + - ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init + - dm: remove flush_scheduled_work() during local_exit() + - nfs4trace: fix state manager flag printing + - NFS: fix disabling of swap + - drm/i915/pvc: Implement recommended caching policy + - drm/i915/pvc: Annotate two more workaround/tuning registers as MCR + - drm/i915: Fix GEN8_MISCCPCTL + - spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one() + - ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared + - HID: bigben: use spinlock to protect concurrent accesses + - HID: bigben_worker() remove unneeded check on report_field + - HID: bigben: use spinlock to safely schedule workers + - hid: bigben_probe(): validate report count + - ALSA: hda/hdmi: Register with vga_switcheroo on Dual GPU Macbooks + - drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt() + - NFSD: enhance inter-server copy cleanup + - NFSD: fix leaked reference count of nfsd4_ssc_umount_item + - nfsd: fix race to check ls_layouts + - nfsd: clean up potential nfsd_file refcount leaks in COPY codepath + - NFSD: fix problems with cleanup on errors in nfsd4_copy + - nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open + - nfsd: don't fsync nfsd_files on last close + - NFSD: copy the whole verifier in nfsd_copy_write_verifier + - cifs: Fix lost destroy smbd connection when MR allocate failed + - cifs: Fix warning and UAF when destroy the MR list + - cifs: use tcon allocation functions even for dummy tcon + - gfs2: jdata writepage fix + - perf llvm: Fix inadvertent file creation + - leds: led-core: Fix refcount leak in of_led_get() + - leds: is31fl319x: Wrap mutex_destroy() for devm_add_action_or_rest() + - leds: simatic-ipc-leds-gpio: Make sure we have the GPIO providing driver + - tools/tracing/rtla: osnoise_hist: use total duration for average calculation + - perf inject: Use perf_data__read() for auxtrace + - perf intel-pt: Do not try to queue auxtrace data on pipe + - perf stat: Hide invalid uncore event output for aggr mode + - perf jevents: Correct bad character encoding + - perf test bpf: Skip test if kernel-debuginfo is not present + - perf tools: Fix auto-complete on aarch64 + - perf stat: Avoid merging/aggregating metric counts twice + - sparc: allow PM configs for sparc32 COMPILE_TEST + - selftests: find echo binary to use -ne options + - selftests/ftrace: Fix bash specific "==" operator + - selftests: use printf instead of echo -ne + - perf record: Fix segfault with --overwrite and --max-size + - printf: fix errname.c list + - perf tests stat_all_metrics: Change true workload to sleep workload for + system wide check + - objtool: add UACCESS exceptions for __tsan_volatile_read/write + - selftests/ftrace: Fix probepoint testcase to ignore __pfx_* symbols + - sysctl: fix proc_dobool() usability + - mfd: rk808: Re-add rk808-clkout to RK818 + - mfd: cs5535: Don't build on UML + - mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read() + - dmaengine: idxd: Set traffic class values in GRPCFG on DSA 2.0 + - RDMA/erdma: Fix refcount leak in erdma_mmap + - dmaengine: HISI_DMA should depend on ARCH_HISI + - RDMA/hns: Fix refcount leak in hns_roce_mmap + - iio: light: tsl2563: Do not hardcode interrupt trigger type + - usb: gadget: fusb300_udc: free irq on the error path in fusb300_probe() + - i2c: designware: fix i2c_dw_clk_rate() return size to be u32 + - i2c: qcom-geni: change i2c_master_hub to static + - soundwire: cadence: Don't overflow the command FIFOs + - driver core: fix potential null-ptr-deref in device_add() + - kobject: Fix slab-out-of-bounds in fill_kobj_path() + - alpha/boot/tools/objstrip: fix the check for ELF header + - media: uvcvideo: Check for INACTIVE in uvc_ctrl_is_accessible() + - media: uvcvideo: Implement mask for V4L2_CTRL_TYPE_MENU + - media: uvcvideo: Refactor uvc_ctrl_mappings_uvcXX + - media: uvcvideo: Refactor power_line_frequency_controls_limited + - coresight: etm4x: Fix accesses to TRCSEQRSTEVR and TRCSEQSTR + - coresight: cti: Prevent negative values of enable count + - coresight: cti: Add PM runtime call in enable_store + - usb: typec: intel_pmc_mux: Don't leak the ACPI device reference count + - PCI/IOV: Enlarge virtfn sysfs name buffer + - PCI: switchtec: Return -EFAULT for copy_to_user() errors + - PCI: endpoint: pci-epf-vntb: Add epf_ntb_mw_bar_clear() num_mws kernel-doc + - hwtracing: hisi_ptt: Only add the supported devices to the filters list + - tty: serial: fsl_lpuart: disable Rx/Tx DMA in lpuart32_shutdown() + - tty: serial: fsl_lpuart: clear LPUART Status Register in lpuart32_shutdown() + - serial: tegra: Add missing clk_disable_unprepare() in tegra_uart_hw_init() + - Revert "char: pcmcia: cm4000_cs: Replace mdelay with usleep_range in + set_protocol" + - eeprom: idt_89hpesx: Fix error handling in idt_init() + - applicom: Fix PCI device refcount leak in applicom_init() + - firmware: stratix10-svc: add missing gen_pool_destroy() in + stratix10_svc_drv_probe() + - firmware: stratix10-svc: fix error handle while alloc/add device failed + - VMCI: check context->notify_page after call to get_user_pages_fast() to + avoid GPF + - mei: pxp: Use correct macros to initialize uuid_le + - misc/mei/hdcp: Use correct macros to initialize uuid_le + - misc: fastrpc: Fix an error handling path in fastrpc_rpmsg_probe() + - iommu/exynos: Fix error handling in exynos_iommu_init() + - driver core: fix resource leak in device_add() + - driver core: location: Free struct acpi_pld_info *pld before return false + - drivers: base: transport_class: fix possible memory leak + - drivers: base: transport_class: fix resource leak when + transport_add_device() fails + - firmware: dmi-sysfs: Fix null-ptr-deref in dmi_sysfs_register_handle + - selftests: iommu: Fix test_cmd_destroy_access() call in user_copy + - iommufd: Add three missing structures in ucmd_buffer + - fotg210-udc: Add missing completion handler + - dmaengine: dw-edma: Fix missing src/dst address of interleaved xfers + - fpga: microchip-spi: move SPI I/O buffers out of stack + - fpga: microchip-spi: rewrite status polling in a time measurable way + - usb: early: xhci-dbc: Fix a potential out-of-bound memory access + - tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case + - RDMA/cxgb4: add null-ptr-check after ip_dev_find() + - usb: musb: mediatek: don't unregister something that wasn't registered + - usb: gadget: configfs: Restrict symlink creation is UDC already binded + - phy: mediatek: remove temporary variable @mask_ + - PCI: mt7621: Delay phy ports initialization + - iommu/vt-d: Set No Execute Enable bit in PASID table entry + - power: supply: remove faulty cooling logic + - RDMA/siw: Fix user page pinning accounting + - RDMA/cxgb4: Fix potential null-ptr-deref in pass_establish() + - usb: max-3421: Fix setting of I/O pins + - RDMA/irdma: Cap MSIX used to online CPUs + 1 + - serial: fsl_lpuart: fix RS485 RTS polariy inverse issue + - tty: serial: imx: disable Ageing Timer interrupt request irq + - driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links + - driver core: fw_devlink: Don't purge child fwnode's consumer links + - driver core: fw_devlink: Allow marking a fwnode link as being part of a + cycle + - driver core: fw_devlink: Consolidate device link flag computation + - driver core: fw_devlink: Improve check for fwnode with no device/driver + - driver core: fw_devlink: Make cycle detection more robust + - mtd: mtdpart: Don't create platform device that'll never probe + - usb: host: fsl-mph-dr-of: reuse device_set_of_node_from_dev + - dmaengine: dw-edma: Fix readq_ch() return value truncation + - PCI: Fix dropping valid root bus resources with .end = zero + - phy: rockchip-typec: fix tcphy_get_mode error case + - PCI: qcom: Fix host-init error handling + - iw_cxgb4: Fix potential NULL dereference in c4iw_fill_res_cm_id_entry() + - iommu: Fix error unwind in iommu_group_alloc() + - iommu/amd: Do not identity map v2 capable device when snp is enabled + - dmaengine: sf-pdma: pdma_desc memory leak fix + - dmaengine: dw-axi-dmac: Do not dereference NULL structure + - dmaengine: ptdma: check for null desc before calling pt_cmd_callback + - iommu/vt-d: Fix error handling in sva enable/disable paths + - iommu/vt-d: Allow to use flush-queue when first level is default + - RDMA/rxe: Cleanup mr_check_range + - RDMA/rxe: Move rxe_map_mr_sg to rxe_mr.c + - RDMA-rxe: Isolate mr code from atomic_reply() + - RDMA-rxe: Isolate mr code from atomic_write_reply() + - RDMA/rxe: Cleanup page variables in rxe_mr.c + - RDMA/rxe: Replace rxe_map and rxe_phys_buf by xarray + - Subject: RDMA/rxe: Handle zero length rdma + - RDMA/mana_ib: Fix a bug when the PF indicates more entries for registering + memory on first packet + - RDMA/rxe: Fix missing memory barriers in rxe_queue.h + - IB/hfi1: Fix math bugs in hfi1_can_pin_pages() + - IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors + - Revert "remoteproc: qcom_q6v5_mss: map/unmap metadata region before/after + use" + - remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers + - media: ti: cal: fix possible memory leak in cal_ctx_create() + - media: platform: ti: Add missing check for devm_regulator_get + - media: imx: imx7-media-csi: fix missing clk_disable_unprepare() in + imx7_csi_init() + - powerpc: Remove linker flag from KBUILD_AFLAGS + - s390/vdso: Drop '-shared' from KBUILD_CFLAGS_64 + - builddeb: clean generated package content + - media: max9286: Fix memleak in max9286_v4l2_register() + - media: ov2740: Fix memleak in ov2740_init_controls() + - media: ov5675: Fix memleak in ov5675_init_controls() + - media: i2c: tc358746: fix missing return assignment + - media: i2c: tc358746: fix ignoring read error in g_register callback + - media: i2c: tc358746: fix possible endianness issue + - media: ov5640: Fix soft reset sequence and timings + - media: ov5640: Handle delays when no reset_gpio set + - media: mc: Get media_device directly from pad + - media: i2c: ov772x: Fix memleak in ov772x_probe() + - media: i2c: imx219: Split common registers from mode tables + - media: i2c: imx219: Fix binning for RAW8 capture + - media: platform: mtk-mdp3: Fix return value check in mdp_probe() + - media: camss: csiphy-3ph: avoid undefined behavior + - media: platform: mtk-mdp3: fix Kconfig dependencies + - media: v4l2-jpeg: correct the skip count in jpeg_parse_app14_data + - media: v4l2-jpeg: ignore the unknown APP14 marker + - media: hantro: Fix JPEG encoder ENUM_FRMSIZE on RK3399 + - media: imx-jpeg: Apply clk_bulk api instead of operating specific clk + - media: amphion: correct the unspecified color space + - media: drivers/media/v4l2-core/v4l2-h264 : add detection of null pointers + - media: rc: Fix use-after-free bugs caused by ene_tx_irqsim() + - media: atomisp: fix videobuf2 Kconfig depenendency + - media: atomisp: Only set default_run_mode on first open of a stream/asd + - media: i2c: ov7670: 0 instead of -EINVAL was returned + - media: usb: siano: Fix use after free bugs caused by do_submit_urb + - media: saa7134: Use video_unregister_device for radio_dev + - rpmsg: glink: Avoid infinite loop on intent for missing channel + - rpmsg: glink: Release driver_override + - ARM: OMAP2+: omap4-common: Fix refcount leak bug + - arm64: dts: qcom: msm8996: Add additional A2NoC clocks + - udf: Define EFSCORRUPTED error code + - context_tracking: Fix noinstr vs KASAN + - exit: Detect and fix irq disabled state in oops + - ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy + - fs: Use CHECK_DATA_CORRUPTION() when kernel bugs are detected + - blk-iocost: fix divide by 0 error in calc_lcoefs() + - blk-cgroup: dropping parent refcount after pd_free_fn() is done + - blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and + blkcg_deactivate_policy() + - trace/blktrace: fix memory leak with using debugfs_lookup() + - btrfs: scrub: improve tree block error reporting + - arm64: zynqmp: Enable hs termination flag for USB dwc3 controller + - cpuidle, intel_idle: Fix CPUIDLE_FLAG_INIT_XSTATE + - x86/fpu: Don't set TIF_NEED_FPU_LOAD for PF_IO_WORKER threads + - cpuidle: drivers: firmware: psci: Dont instrument suspend code + - cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG + - perf/x86/intel/uncore: Add Meteor Lake support + - wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect() + - wifi: ath11k: fix monitor mode bringup crash + - wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds() + - rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks + - rcu: Suppress smp_processor_id() complaint in + synchronize_rcu_expedited_wait() + - srcu: Delegate work to the boot cpu if using SRCU_SIZE_SMALL + - rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug + - rcu-tasks: Handle queue-shrink/callback-enqueue race condition + - wifi: ath11k: debugfs: fix to work with multiple PCI devices + - thermal: intel: Fix unsigned comparison with less than zero + - timers: Prevent union confusion from unexpected restart_syscall() + - x86/bugs: Reset speculation control settings on init + - bpftool: Always disable stack protection for BPF objects + - wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out- + of-bounds + - wifi: rtw89: fix assignation of TX BD RAM table + - wifi: mt7601u: fix an integer underflow + - inet: fix fast path in __inet_hash_connect() + - ice: restrict PTP HW clock freq adjustments to 100, 000, 000 PPB + - ice: add missing checks for PF vsi type + - Compiler attributes: GCC cold function alignment workarounds + - ACPI: Don't build ACPICA with '-Os' + - bpf, docs: Fix modulo zero, division by zero, overflow, and underflow + - thermal: intel: intel_pch: Add support for Wellsburg PCH + - clocksource: Suspend the watchdog temporarily when high read latency + detected + - crypto: hisilicon: Wipe entire pool on error + - net: bcmgenet: Add a check for oversized packets + - m68k: Check syscall_trace_enter() return code + - s390/mm,ptdump: avoid Kasan vs Memcpy Real markers swapping + - netfilter: nf_tables: NULL pointer dereference in nf_tables_updobj() + - can: isotp: check CAN address family in isotp_bind() + - gcc-plugins: drop -std=gnu++11 to fix GCC 13 build + - tools/power/x86/intel-speed-select: Add Emerald Rapid quirk + - platform/x86: dell-ddv: Add support for interface version 3 + - wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup + - ACPI: video: Fix Lenovo Ideapad Z570 DMI match + - net/mlx5: fw_tracer: Fix debug print + - coda: Avoid partial allocation of sig_inputArgs + - uaccess: Add minimum bounds check on kernel buffer size + - s390/idle: mark arch_cpu_idle() noinstr + - time/debug: Fix memory leak with using debugfs_lookup() + - PM: domains: fix memory leak with using debugfs_lookup() + - PM: EM: fix memory leak with using debugfs_lookup() + - Bluetooth: Fix issue with Actions Semi ATS2851 based devices + - Bluetooth: btusb: Add new PID/VID 0489:e0f2 for MT7921 + - Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE + - wifi: rtw89: debug: avoid invalid access on RTW89_DBG_SEL_MAC_30 + - hv_netvsc: Check status in SEND_RNDIS_PKT completion message + - s390/kfence: fix page fault reporting + - devlink: Fix TP_STRUCT_entry in trace of devlink health report + - scm: add user copy checks to put_cmsg() + - drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Tab 3 X90F + - drm: panel-orientation-quirks: Add quirk for DynaBook K50 + - drm/amd/display: Reduce expected sdp bandwidth for dcn321 + - drm/amd/display: Revert Reduce delay when sink device not able to ACK 00340h + write + - drm/amd/display: Fix potential null-deref in dm_resume + - drm/omap: dsi: Fix excessive stack usage + - HID: Add Mapping for System Microphone Mute + - drm/tiny: ili9486: Do not assume 8-bit only SPI controllers + - drm/amd/display: Defer DIG FIFO disable after VID stream enable + - drm/radeon: free iio for atombios when driver shutdown + - drm/amd: Avoid BUG() for case of SRIOV missing IP version + - drm/amdkfd: Page aligned memory reserve size + - scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write + - Revert "fbcon: don't lose the console font across generic->chip driver + switch" + - drm/amd: Avoid ASSERT for some message failures + - drm: amd: display: Fix memory leakage + - drm/amd/display: fix mapping to non-allocated address + - HID: uclogic: Add frame type quirk + - HID: uclogic: Add battery quirk + - HID: uclogic: Add support for XP-PEN Deco Pro SW + - HID: uclogic: Add support for XP-PEN Deco Pro MW + - drm/msm/dsi: Add missing check for alloc_ordered_workqueue + - drm: rcar-du: Add quirk for H3 ES1.x pclk workaround + - drm: rcar-du: Fix setting a reserved bit in DPLLCR + - drm/drm_print: correct format problem + - drm/amd/display: Set hvm_enabled flag for S/G mode + - drm/client: Test for connectors before sending hotplug event + - habanalabs: extend fatal messages to contain PCI info + - habanalabs: fix bug in timestamps registration code + - docs/scripts/gdb: add necessary make scripts_gdb step + - drm/msm/dpu: Add DSC hardware blocks to register snapshot + - ASoC: soc-compress: Reposition and add pcm_mutex + - ASoC: kirkwood: Iterate over array indexes instead of using pointer math + - regulator: max77802: Bounds check regulator id against opmode + - regulator: s5m8767: Bounds check id indexing into arrays + - Revert "drm/amdgpu: TA unload messages are not actually sent to psp when + amdgpu is uninstalled" + - drm/amd/display: fix FCLK pstate change underflow + - gfs2: Improve gfs2_make_fs_rw error handling + - hwmon: (coretemp) Simplify platform device handling + - hwmon: (nct6775) Directly call ASUS ACPI WMI method + - hwmon: (nct6775) B650/B660/X670 ASUS boards support + - pinctrl: at91: use devm_kasprintf() to avoid potential leaks + - drm/amd/display: Do not commit pipe when updating DRR + - scsi: snic: Fix memory leak with using debugfs_lookup() + - scsi: ufs: core: Fix device management cmd timeout flow + - HID: logitech-hidpp: Don't restart communication if not necessary + - drm/amd/display: Enable P-state validation checks for DCN314 + - drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5 + - drm/amd/display: Disable HUBP/DPP PG on DCN314 for now + - drm/amd/display: disable SubVP + DRR to prevent underflow + - dm thin: add cond_resched() to various workqueue loops + - dm cache: add cond_resched() to various workqueue loops + - nfsd: zero out pointers after putting nfsd_files on COPY setup error + - nfsd: don't hand out delegation on setuid files being opened for write + - cifs: prevent data race in smb2_reconnect() + - drm/i915/mtl: Correct implementation of Wa_18018781329 + - drm/shmem-helper: Revert accidental non-GPL export + - driver core: fw_devlink: Avoid spurious error message + - wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu + - firmware: coreboot: framebuffer: Ignore reserved pixel color bits + - block: don't allow multiple bios for IOCB_NOWAIT issue + - block: clear bio->bi_bdev when putting a bio back in the cache + - block: be a bit more careful in checking for NULL bdev while polling + - rtc: pm8xxx: fix set-alarm race + - ipmi: ipmb: Fix the MODULE_PARM_DESC associated to 'retry_time_ms' + - ipmi:ssif: resend_msg() cannot fail + - ipmi_ssif: Rename idle state and check + - ipmi:ssif: Add a timer between request retries + - io_uring: Replace 0-length array with flexible array + - io_uring: use user visible tail in io_uring_poll() + - io_uring: handle TIF_NOTIFY_RESUME when checking for task_work + - io_uring: add a conditional reschedule to the IOPOLL cancelation loop + - io_uring: add reschedule point to handle_tw_list() + - io_uring/rsrc: disallow multi-source reg buffers + - io_uring: remove MSG_NOSIGNAL from recvmsg + - io_uring/poll: allow some retries for poll triggering spuriously + - io_uring: fix fget leak when fs don't support nowait buffered read + - s390/extmem: return correct segment type in __segment_load() + - s390: discard .interp section + - s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler + - s390/kprobes: fix current_kprobe never cleared after kprobes reenter + - KVM: s390: disable migration mode when dirty tracking is disabled + - cifs: improve checking of DFS links over STATUS_OBJECT_NAME_INVALID + - cifs: Fix uninitialized memory read in smb3_qfs_tcon() + - cifs: Fix uninitialized memory reads for oparms.mode + - cifs: fix mount on old smb servers + - cifs: introduce cifs_io_parms in smb2_async_writev() + - cifs: split out smb3_use_rdma_offload() helper + - cifs: don't try to use rdma offload on encrypted connections + - cifs: Check the lease context if we actually got a lease + - cifs: return a single-use cfid if we did not get a lease + - scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization + - scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info() + - scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi + - btrfs: hold block group refcount during async discard + - btrfs: sysfs: update fs features directory asynchronously + - locking/rwsem: Prevent non-first waiter from spinning in down_write() + slowpath + - ksmbd: fix wrong data area length for smb2 lock request + - ksmbd: do not allow the actual frame length to be smaller than the rfc1002 + length + - ksmbd: fix possible memory leak in smb2_lock() + - torture: Fix hang during kthread shutdown phase + - ARM: dts: exynos: correct HDMI phy compatible in Exynos4 + - io_uring: mark task TASK_RUNNING before handling resume/task work + - hfs: fix missing hfs_bnode_get() in __hfs_bnode_create + - fs: hfsplus: fix UAF issue in hfsplus_put_super + - exfat: fix reporting fs error when reading dir beyond EOF + - exfat: fix unexpected EOF while reading dir + - exfat: redefine DIR_DELETED as the bad cluster number + - exfat: fix inode->i_blocks for non-512 byte sector size device + - fs: dlm: start midcomms before scand + - fs: dlm: fix use after free in midcomms commit + - fs: dlm: be sure to call dlm_send_queue_flush() + - fs: dlm: fix race setting stop tx flag + - fs: dlm: don't set stop rx flag after node reset + - fs: dlm: move sending fin message into state change handling + - fs: dlm: send FIN ack back in right cases + - f2fs: fix information leak in f2fs_move_inline_dirents() + - f2fs: retry to update the inode page given data corruption + - f2fs: fix cgroup writeback accounting with fs-layer encryption + - f2fs: fix kernel crash due to null io->bio + - f2fs: Revert "f2fs: truncate blocks in batch in __complete_revoke_list()" + - ocfs2: fix defrag path triggering jbd2 ASSERT + - ocfs2: fix non-auto defrag path not working issue + - fs/cramfs/inode.c: initialize file_ra_state + - selftests/landlock: Skip overlayfs tests when not supported + - selftests/landlock: Test ptrace as much as possible with Yama + - udf: Truncate added extents on failed expansion + - udf: Do not bother merging very long extents + - udf: Do not update file length for failed writes to inline files + - udf: Preserve link count of system files + - udf: Detect system inodes linked into directory hierarchy + - udf: Fix file corruption when appending just after end of preallocated + extent + - md: don't update recovery_cp when curr_resync is ACTIVE + - KVM: Destroy target device if coalesced MMIO unregistration fails + - KVM: VMX: Fix crash due to uninitialized current_vmcs + - KVM: Register /dev/kvm as the _very_ last thing during initialization + - KVM: x86: Purge "highest ISR" cache when updating APICv state + - KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps + - KVM: x86: Don't inhibit APICv/AVIC on xAPIC ID "change" if APIC is disabled + - KVM: x86: Don't inhibit APICv/AVIC if xAPIC ID mismatch is due to 32-bit ID + - KVM: SVM: Flush the "current" TLB when activating AVIC + - KVM: SVM: Process ICR on AVIC IPI delivery failure due to invalid target + - KVM: SVM: Don't put/load AVIC when setting virtual APIC mode + - KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI + - KVM: x86: Inject #GP on x2APIC WRMSR that sets reserved bits 63:32 + - KVM: SVM: Fix potential overflow in SEV's send|receive_update_data() + - KVM: SVM: hyper-v: placate modpost section mismatch error + - selftests: x86: Fix incorrect kernel headers search path + - x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows) + - x86/crash: Disable virt in core NMI crash handler to avoid double shootdown + - x86/reboot: Disable virtualization in an emergency if SVM is supported + - x86/reboot: Disable SVM, not just VMX, when stopping CPUs + - x86/kprobes: Fix __recover_optprobed_insn check optimizing logic + - x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe + range + - x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter + - x86/microcode/AMD: Add a @cpu parameter to the reloading functions + - x86/microcode/AMD: Fix mixed steppings support + - x86/speculation: Allow enabling STIBP with legacy IBRS + - Documentation/hw-vuln: Document the interaction between IBRS and STIBP + - virt/sev-guest: Return -EIO if certificate buffer is not large enough + - brd: mark as nowait compatible + - brd: return 0/-error from brd_insert_page() + - brd: check for REQ_NOWAIT and set correct page allocation mask + - ima: fix error handling logic when file measurement failed + - ima: Align ima_file_mmap() parameters with mmap_file LSM hook + - selftests/powerpc: Fix incorrect kernel headers search path + - selftests/ftrace: Fix eprobe syntax test case to check filter support + - selftests: sched: Fix incorrect kernel headers search path + - selftests: core: Fix incorrect kernel headers search path + - selftests: pid_namespace: Fix incorrect kernel headers search path + - selftests: arm64: Fix incorrect kernel headers search path + - selftests: clone3: Fix incorrect kernel headers search path + - selftests: pidfd: Fix incorrect kernel headers search path + - selftests: membarrier: Fix incorrect kernel headers search path + - selftests: kcmp: Fix incorrect kernel headers search path + - selftests: media_tests: Fix incorrect kernel headers search path + - selftests: gpio: Fix incorrect kernel headers search path + - selftests: filesystems: Fix incorrect kernel headers search path + - selftests: user_events: Fix incorrect kernel headers search path + - selftests: ptp: Fix incorrect kernel headers search path + - selftests: sync: Fix incorrect kernel headers search path + - selftests: rseq: Fix incorrect kernel headers search path + - selftests: move_mount_set_group: Fix incorrect kernel headers search path + - selftests: mount_setattr: Fix incorrect kernel headers search path + - selftests: perf_events: Fix incorrect kernel headers search path + - selftests: ipc: Fix incorrect kernel headers search path + - selftests: futex: Fix incorrect kernel headers search path + - selftests: drivers: Fix incorrect kernel headers search path + - selftests: dmabuf-heaps: Fix incorrect kernel headers search path + - selftests: vm: Fix incorrect kernel headers search path + - selftests: seccomp: Fix incorrect kernel headers search path + - irqdomain: Fix association race + - irqdomain: Fix disassociation race + - irqdomain: Look for existing mapping only once + - irqdomain: Drop bogus fwspec-mapping error handling + - irqdomain: Refactor __irq_domain_alloc_irqs() + - irqdomain: Fix mapping-creation race + - irqdomain: Fix domain registration race + - crypto: qat - fix out-of-bounds read + - mm/damon/paddr: fix missing folio_put() + - ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls() + - ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC + - jbd2: fix data missing when reusing bh which is ready to be checkpointed + - ext4: optimize ea_inode block expansion + - ext4: refuse to create ea block when umounted + - cxl/pmem: Fix nvdimm registration races + - Input: exc3000 - properly stop timer on shutdown + - mtd: spi-nor: sfdp: Fix index value for SCCR dwords + - mtd: spi-nor: spansion: Consider reserved bits in CFR5 register + - dm: send just one event on resize, not two + - dm: add cond_resched() to dm_wq_work() + - dm: add cond_resched() to dm_wq_requeue_work() + - wifi: rtw88: use RTW_FLAG_POWERON flag to prevent to power on/off twice + - wifi: rtl8xxxu: Use a longer retry limit of 48 + - wifi: ath11k: allow system suspend to survive ath11k + - wifi: cfg80211: Fix use after free for wext + - wifi: cfg80211: Set SSID if it is not already set + - cpuidle: add ARCH_SUSPEND_POSSIBLE dependencies + - qede: fix interrupt coalescing configuration + - thermal: intel: powerclamp: Fix cur_state for multi package system + - dm flakey: fix logic when corrupting a bio + - dm cache: free background tracker's queued work in btracker_destroy + - dm flakey: don't corrupt the zero page + - dm flakey: fix a bug with 32-bit highmem systems + - hwmon: (peci/cputemp) Fix off-by-one in coretemp_label allocation + - hwmon: (nct6775) Fix incorrect parenthesization in nct6775_write_fan_div() + - spi: intel: Check number of chip selects after reading the descriptor + - ARM: dts: qcom: sdx65: Add Qcom SMMU-500 as the fallback for IOMMU node + - ARM: dts: qcom: sdx55: Add Qcom SMMU-500 as the fallback for IOMMU node + - ARM: dts: exynos: correct TMU phandle in Exynos4210 + - ARM: dts: exynos: correct TMU phandle in Exynos4 + - ARM: dts: exynos: correct TMU phandle in Odroid XU3 family + - ARM: dts: exynos: correct TMU phandle in Exynos5250 + - ARM: dts: exynos: correct TMU phandle in Odroid XU + - ARM: dts: exynos: correct TMU phandle in Odroid HC1 + - arm64: acpi: Fix possible memory leak of ffh_ctxt + - arm64: mm: hugetlb: Disable HUGETLB_PAGE_OPTIMIZE_VMEMMAP + - arm64: Reset KASAN tag in copy_highpage with HW tags only + - fuse: add inode/permission checks to fileattr_get/fileattr_set + - rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails + - ceph: update the time stamps and try to drop the suid/sgid + - regulator: core: Use ktime_get_boottime() to determine how long a regulator + was off + - panic: fix the panic_print NMI backtrace setting + - mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON + - genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced + - genirq/msi: Take the per-device MSI lock before validating the control + structure + - spi: spi-sn-f-ospi: fix duplicate flag while assigning to mode_bits + - alpha: fix FEN fault handling + - dax/kmem: Fix leak of memory-hotplug resources + - mips: fix syscall_get_nr + - media: ipu3-cio2: Fix PM runtime usage_count in driver unbind + - remoteproc/mtk_scp: Move clk ops outside send_lock + - vfio: Fix NULL pointer dereference caused by uninitialized group->iommufd + - docs: gdbmacros: print newest record + - mm: memcontrol: deprecate charge moving + - mm/thp: check and bail out if page in deferred queue already + - ktest.pl: Give back console on Ctrt^C on monitor + - kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list + - ktest.pl: Fix missing "end_monitor" when machine check fails + - ktest.pl: Add RUN_TIMEOUT option with default unlimited + - memory tier: release the new_memtier in find_create_memory_tier() + - ring-buffer: Handle race between rb_move_tail and rb_check_pages + - tools/bootconfig: fix single & used for logical condition + - tracing/eprobe: Fix to add filter on eprobe description in README file + - iommu/amd: Add a length limitation for the ivrs_acpihid command-line + parameter + - scsi: aacraid: Allocate cmd_priv with scsicmd + - scsi: qla2xxx: Fix link failure in NPIV environment + - scsi: qla2xxx: Check if port is online before sending ELS + - scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests + - scsi: qla2xxx: Remove unintended flag clearing + - scsi: qla2xxx: Fix erroneous link down + - scsi: qla2xxx: Remove increment of interface err cnt + - scsi: ses: Don't attach if enclosure has no components + - scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process() + - scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses + - scsi: ses: Fix possible desc_ptr out-of-bounds accesses + - scsi: ses: Fix slab-out-of-bounds in ses_intf_remove() + - RISC-V: add a spin_shadow_stack declaration + - riscv: Avoid enabling interrupts in die() + - riscv: mm: fix regression due to update_mmu_cache change + - riscv: jump_label: Fixup unaligned arch_static_branch function + - riscv: ftrace: Fixup panic by disabling preemption + - riscv, mm: Perform BPF exhandler fixup on page fault + - riscv: ftrace: Remove wasted nops for !RISCV_ISA_C + - riscv: ftrace: Reduce the detour code size to half + - MIPS: DTS: CI20: fix otg power gpio + - PCI/PM: Observe reset delay irrespective of bridge_d3 + - PCI: Unify delay handling for reset and resume + - PCI: hotplug: Allow marking devices as disconnected during bind/unbind + - PCI: Avoid FLR for AMD FCH AHCI adapters + - PCI/DPC: Await readiness of secondary bus after reset + - bus: mhi: ep: Only send -ENOTCONN status if client driver is available + - bus: mhi: ep: Move chan->lock to the start of processing queued ch ring + - bus: mhi: ep: Save channel state locally during suspend and resume + - iommufd: Make sure to zero vfio_iommu_type1_info before copying to user + - iommufd: Do not add the same hwpt to the ioas->hwpt_list twice + - iommu/vt-d: Avoid superfluous IOTLB tracking in lazy mode + - iommu/vt-d: Fix PASID directory pointer coherency + - vfio/type1: exclude mdevs from VFIO_UPDATE_VADDR + - vfio/type1: prevent underflow of locked_vm via exec() + - vfio/type1: track locked_vm per dma + - vfio/type1: restore locked_vm + - drm/amd: Fix initialization for nbio 7.5.1 + - drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv + - drm/radeon: Fix eDP for single-display iMac11,2 + - drm/i915: Don't use stolen memory for ring buffers with LLC + - drm/i915: Don't use BAR mappings for ring buffers with LLC + - drm/gud: Fix UBSAN warning + - drm/edid: fix AVI infoframe aspect ratio handling + - drm/edid: fix parsing of 3D modes from HDMI VSDB + - qede: avoid uninitialized entries in coal_entry array + - brd: use radix_tree_maybe_preload instead of radix_tree_preload + - net: avoid double iput when sock_alloc_file fails + - Linux 6.2.3 + + * Miscellaneous Ubuntu changes + - [Config] update annotations after applying 6.2.3 stable patches + - [Config] update annotations after applying 6.2.6 stable patches + + -- Andrea Righi Tue, 14 Mar 2023 16:43:44 +0100 + +linux (6.2.0-16.16) lunar; urgency=medium + + * lunar/linux: 6.2.0-16.16 -proposed tracker (LP: #2009914) + + * linux-libc-dev is no longer multi-arch safe (LP: #2009355) + - Revert "UBUNTU: [Packaging] install headers to debian/linux-libc-dev + directly" + + * linux: CONFIG_SERIAL_8250_MID=y (LP: #2009283) + - [Config] enable CONFIG_SERIAL_8250_MID=y + + * cpufreq: intel_pstate: Update Balance performance EPP for Sapphire Rapids + (LP: #2008519) + - cpufreq: intel_pstate: Adjust balance_performance EPP for Sapphire Rapids + + -- Andrea Righi Fri, 10 Mar 2023 18:34:28 +0100 + +linux (6.2.0-15.15) lunar; urgency=medium + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: document annotations headers + + -- Andrea Righi Fri, 10 Mar 2023 07:36:59 +0100 + +linux (6.2.0-14.14) lunar; urgency=medium + + * lunar/linux: 6.2.0-14.14 -proposed tracker (LP: #2009856) + + * Miscellaneous Ubuntu changes + - [Packaging] rust: add rust build dependencies to all arches + - [Packaging] Support skipped dkms modules + - [Packaging] actually enforce set -e in dkms-build--nvidia-N + - [Packaging] Preserve the correct log file variable value + - [Packaging] update getabis + + -- Andrea Righi Thu, 09 Mar 2023 16:40:36 +0100 + +linux (6.2.0-13.13) lunar; urgency=medium + + * lunar/linux: 6.2.0-13.13 -proposed tracker (LP: #2009704) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/master) + + * mt7921: add support of MTFG table (LP: #2009642) + - wifi: mt76: mt7921: add support to update fw capability with MTFG table + + -- Andrea Righi Wed, 08 Mar 2023 14:40:25 +0100 + +linux (6.2.0-12.12) lunar; urgency=medium + + * lunar/linux: 6.2.0-12.12 -proposed tracker (LP: #2009698) + + * Miscellaneous Ubuntu changes + - SAUCE: enforce rust availability only on x86_64 + - [Config] update CONFIG_RUST_IS_AVAILABLE + + -- Andrea Righi Wed, 08 Mar 2023 12:50:15 +0100 + +linux (6.2.0-11.11) lunar; urgency=medium + + * lunar/linux: 6.2.0-11.11 -proposed tracker (LP: #2009697) + + * Miscellaneous Ubuntu changes + - [Packaging] do not stop the build if rust is not available + + -- Andrea Righi Wed, 08 Mar 2023 12:24:55 +0100 + +linux (6.2.0-10.10) lunar; urgency=medium + + * lunar/linux: 6.2.0-10.10 -proposed tracker (LP: #2009673) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/master) + + * enable Rust support in the kernel (LP: #2007654) + - [Packaging] propagate makefile variables to kernelconfig + - SAUCE: rust: fix regexp in scripts/is_rust_module.sh + - SAUCE: scripts: rust: drop is_rust_module.sh + - SAUCE: rust: allow to use INIT_STACK_ALL_ZERO + - SAUCE: scripts: Exclude Rust CUs with pahole + - SAUCE: modpost: support arbitrary symbol length in modversion + - SAUCE: allows to enable Rust with modversions + - SAUCE: rust: properly detect the version of libclang used by bindgen + - [Packaging] rust: add the proper make flags to enable rust support + - [Packaging] add rust dependencies + - [Packaging] bpftool: always use vmlinux to generate headers + - [Packaging] run rustavailable target as debugging before build + - [Config] enable Rust support + + * Fail to output sound to external monitor which connects via docking station + (LP: #2009024) + - [Config] Enable CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM + + * Miscellaneous Ubuntu changes + - SAUCE: Makefile: replace rsync with tar + + -- Andrea Righi Wed, 08 Mar 2023 12:01:56 +0100 + +linux (6.2.0-1.1) lunar; urgency=medium + + * lunar/linux: 6.2.0-1.1 -proposed tracker (LP: #2009621) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - debian/dkms-versions -- update from kernel-versions (main/master) + + * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) + - SAUCE: apparmor: Add fine grained mediation of posix mqueues + - SAUCE: apparmor: add user namespace creation mediation + + * Lunar update: v6.2.2 upstream stable release (LP: #2009358) + - ALSA: hda: cs35l41: Correct error condition handling + - crypto: arm64/sm4-gcm - Fix possible crash in GCM cryption + - bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state + - vc_screen: don't clobber return value in vcs_read + - drm/amd/display: Move DCN314 DOMAIN power control to DMCUB + - drm/amd/display: Properly reuse completion structure + - scripts/tags.sh: fix incompatibility with PCRE2 + - wifi: rtw88: usb: Set qsel correctly + - wifi: rtw88: usb: send Zero length packets if necessary + - wifi: rtw88: usb: drop now unnecessary URB size check + - usb: dwc3: pci: add support for the Intel Meteor Lake-M + - USB: serial: option: add support for VW/Skoda "Carstick LTE" + - usb: gadget: u_serial: Add null pointer check in gserial_resume + - arm64: dts: uniphier: Fix property name in PXs3 USB node + - usb: typec: pd: Remove usb_suspend_supported sysfs from sink PDO + - USB: core: Don't hold device lock while reading the "descriptors" sysfs file + - Linux 6.2.2 + + * Lunar update: v6.2.1 upstream stable release (LP: #2009127) + - uaccess: Add speculation barrier to copy_from_user() + - x86/alternatives: Introduce int3_emulate_jcc() + - x86/alternatives: Teach text_poke_bp() to patch Jcc.d32 instructions + - x86/static_call: Add support for Jcc tail-calls + - HID: mcp-2221: prevent UAF in delayed work + - wifi: mwifiex: Add missing compatible string for SD8787 + - audit: update the mailing list in MAINTAINERS + - platform/x86/amd/pmf: Add depends on CONFIG_POWER_SUPPLY + - platform/x86: nvidia-wmi-ec-backlight: Add force module parameter + - ext4: Fix function prototype mismatch for ext4_feat_ktype + - randstruct: disable Clang 15 support + - bpf: add missing header file include + - Linux 6.2.1 + + * Fix mediatek wifi driver crash when loading wrong SAR table (LP: #2009118) + - wifi: mt76: mt7921: fix error code of return in mt7921_acpi_read + + * overlayfs mounts as R/O over idmapped mount (LP: #2009065) + - SAUCE: overlayfs: handle idmapped mounts in ovl_do_(set|remove)xattr + + * RaptorLake: Fix the Screen is shaking by onboard HDMI port in mirror mode + (LP: #1993561) + - drm/i915/display: Drop check for doublescan mode in modevalid + - drm/i915/display: Prune Interlace modes for Display >=12 + + * screen flicker after PSR2 enabled (LP: #2007516) + - SAUCE: drm/i915/display/psr: Disable PSR2 sel fetch on panel SHP 5457 + + * [23.04 FEAT] Support for new IBM Z Hardware (IBM z16) - Reset DAT-Protection + facility support (LP: #1982378) + - s390/mm: add support for RDP (Reset DAT-Protection) + + * [23.04 FEAT] zcrypt DD: AP command filtering (LP: #2003637) + - s390/zcrypt: introduce ctfm field in struct CPRBX + + * rtcpie in timers from ubuntu_kernel_selftests randomly failing + (LP: #1814234) + - SAUCE: selftest: rtcpie: Force passing unreliable subtest + + * [23.04 FEAT] Support for List-Directed IPL and re-IPL from ECKD DASD + (LP: #2003394) + - s390/ipl: add DEFINE_GENERIC_LOADPARM() + - s390/ipl: add loadparm parameter to eckd ipl/reipl data + + * Miscellaneous Ubuntu changes + - SAUCE: drm/i915/sseu: fix max_subslices array-index-out-of-bounds access + - SAUCE: mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type + - SAUCE: Revert "fbdev: Make registered_fb[] private to fbmem.c" + - [Packaging] disable signing for ppc64el + - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS + - SAUCE: Revert "arm64/fpsimd: Make kernel_neon_ API _GPL" + + -- Andrea Righi Tue, 07 Mar 2023 18:45:31 +0100 + +linux (6.2.0-0.0) lunar; urgency=medium + + * Empty entry + + -- Andrea Righi Fri, 03 Mar 2023 08:42:43 +0100 + +linux-unstable (6.2.0-10.10) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-10.10 -proposed tracker (LP: #2007818) + + * Built-in camera device dies after runtime suspended (LP: #2007530) + - SAUCE: usb: xhci: Workaround for runpm issue on AMD xHC + + * Miscellaneous Ubuntu changes + - [Config] update annotations after rebase to v6.2 + + [ Upstream Kernel Changes ] + + * Rebase to v6.2 + + -- Andrea Righi Mon, 20 Feb 2023 10:36:20 +0100 + +linux-unstable (6.2.0-9.9) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-9.9 -proposed tracker (LP: #2007069) + + * Move kernel ADT tests to python3 (LP: #2004429) + - [Debian] Use a python3 compatable kernel-testing repo + + * Mediatek FM350-GL wwan module failed to init: Invalid device status 0x1 + (LP: #2002089) + - SAUCE: Revert "net: wwan: t7xx: Add AP CLDMA" + - SAUCE: net: wwan: t7xx: Add AP CLDMA + - SAUCE: net: wwan: t7xx: Infrastructure for early port configuration + - SAUCE: net: wwan: t7xx: PCIe reset rescan + - SAUCE: net: wwan: t7xx: Enable devlink based fw flashing and coredump + collection + - SAUCE: net: wwan: t7xx: Devlink documentation + + * LXD containers using shiftfs on ZFS or TMPFS broken on 5.15.0-48.54 + (LP: #1990849) + - SAUCE: shiftfs: fix -EOVERFLOW inside the container + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: do not drop undefined configs in derivatives + - [Packaging]: annotations: fix _remove_entry() logic + - [Packaging] rsync no longer available on lunar + - [Packaging] annotations: Handle single-line annoation rules + - [Packaging] annotations: Preserve single-line annotation rules + - [Packaging] annotations: Fix linter errors + - [Packaging] annotations: Clean up policy writes + - [Packaging] annotations: Handle tabs in annotations file + - [Packaging] annotations: Fail on invalid lines + - [Packaging] annotations: Write out annotations with notes first + - [Packaging] annotations: Check validity of FLAVOUR_DEP + - [Config] update annotations to split configs with/without notes + - [Packaging] annotations: various code cleanups + - [Config] update annotations after rebase to v6.2-rc8 + + * Miscellaneous upstream changes + - selftests/net: mv bpf/nat6to4.c to net folder + + [ Upstream Kernel Changes ] + + * Rebase to v6.1-rc8 + + -- Andrea Righi Mon, 13 Feb 2023 09:32:18 +0100 + +linux-unstable (6.2.0-8.8) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-8.8 -proposed tracker (LP: #2004229) + + * Miscellaneous Ubuntu changes + - [Packaging] re-enable signing for ppc64el and s390x + - SAUCE: s390/decompressor: specify __decompress() buf len to avoid overflow + + -- Andrea Righi Tue, 31 Jan 2023 08:21:21 +0100 + +linux-unstable (6.2.0-7.7) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-7.7 -proposed tracker (LP: #2004142) + + -- Andrea Righi Mon, 30 Jan 2023 10:23:15 +0100 + +linux-unstable (6.2.0-6.6) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-6.6 -proposed tracker (LP: #2004138) + + * Miscellaneous Ubuntu changes + - [Packaging] debian/rules: Bring back 'editconfigs' + - [Packaging] debian/rules: 1-maintainer.mk -- Use make's if-else + - [Packaging] annotations: make sure to always drop undefined configs + - [Config] update annotations after rebase to v6.2-rc6 + + [ Upstream Kernel Changes ] + + * Rebase to v6.1-rc6 + + -- Andrea Righi Mon, 30 Jan 2023 09:20:26 +0100 + +linux-unstable (6.2.0-5.5) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-5.5 -proposed tracker (LP: #2003682) + + * [23.04] Kernel 6.2 does not boot on s390x (LP: #2003348) + - SAUCE Revert "zstd: import usptream v1.5.2" + - SAUCE: Revert "zstd: Move zstd-common module exports to + zstd_common_module.c" + + * Revoke & rotate to new signing key (LP: #2002812) + - [Packaging] Revoke and rotate to new signing key + + * CVE-2023-0179 + - netfilter: nft_payload: incorrect arithmetics when fetching VLAN header bits + + * [23.04] net/smc: Alibaba patches about tunable buffer sizes may cause errors + and need to be removed (kernel 6.2) (LP: #2003547) + - SAUCE: Revert "net/smc: Unbind r/w buffer size from clcsock and make them + tunable" + - SAUCE: Revert "net/smc: Introduce a specific sysctl for TEST_LINK time" + + * 5.15 stuck at boot on c4.large (LP: #1956780) + - SAUCE: Revert "PCI/MSI: Mask MSI-X vectors only on success" + + * Miscellaneous Ubuntu changes + - [Packaging] scripts/misc/kernelconfig: Disable config checks for mainline + builds + - [Packaging] annotations: add CONFIG_GCC_VERSION to the list of ignored + configs + + -- Andrea Righi Mon, 23 Jan 2023 08:20:26 +0100 + +linux-unstable (6.2.0-4.4) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-4.4 -proposed tracker (LP: #2003051) + + * Miscellaneous Ubuntu changes + - [Packaging] add python3 as a build dependency + - [Packaging] scripts/misc/kernelconfig: Rewrite + + -- Andrea Righi Tue, 17 Jan 2023 09:18:54 +0100 + +linux-unstable (6.2.0-3.3) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-3.3 -proposed tracker (LP: #2002939) + + * Enable kernel config for P2PDMA (LP: #1987394) + - [Config] Enable CONFIG_HSA_AMD_P2P + + * Miscellaneous Ubuntu changes + - SAUCE: (no-up) Remove obj- += foo.o hack + - SAUCE: (no-up) re-add ubuntu/ directory + - [Config] enable EFI handover protocol + - [Packaging] Fix module-check error when modules are compressed + - SAUCE: (no-up) do not remove debian directory by 'make mrproper' + - [Packaging] debian/rules: Drop AUTOBUILD + - [Packaging] debian/rules: Drop NOKERNLOG and PRINTSHAS env variables + - [Packaging] debian/rules: Replace skip variables with skip_checks + - [Packaging] checks/retpoline-check: Make 'skipretpoline' argument optional + - [Packaging] checks/module-signature-check: Add 'skip_checks' argument + - [Packaging] debian/rules: Rename 'skip_dbg' to 'do_dbgsym_package' + - [Packaging] debian/rules: Rename 'skip_checks' to 'do_skip_checks' + - [Packaging] debian/rules: Rename 'full_build' to 'do_full_build' + - [Packaging] debian/rules: Fix PPA debug package builds + - [Packaging] debian/rules: Remove debug package install directory earlier + - [Packaging] debian/rules: Remove unnecessary 'lockme_' variables + - [Packaging] debian/rules: Remove unused target 'diffupstream' + - [Packaging] debian/rules: Mark PHONY targets individually + - [Packaging] debian/rules: Clean up 'help' target output + - [Packaging] debian/rules: Clean up 'printenv' target output + - [Packaging] debian/rules: Add missing 'do_' variables to 'printenv' + - [Config] update annotations after rebase to v6.2-rc4 + + [ Upstream Kernel Changes ] + + * Rebase to v6.1-rc4 + + -- Andrea Righi Mon, 16 Jan 2023 16:01:40 +0100 + +linux-unstable (6.2.0-2.2) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-2.2 -proposed tracker (LP: #2001892) + + * Soundwire support for the Intel RPL Gen 0C40/0C11 platforms (LP: #2000030) + - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C40 product + - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C11 product + + * Miscellaneous Ubuntu changes + - [Config] update toolchain version in annotations + + * Miscellaneous upstream changes + - Revert "UBUNTU: [Packaging] Support skipped dkms modules" + + [ Upstream Kernel Changes ] + + * Rebase to v6.1-rc2 + + -- Andrea Righi Thu, 05 Jan 2023 09:19:55 +0100 + +linux-unstable (6.2.0-1.1) lunar; urgency=medium + + * lunar/linux-unstable: 6.2.0-1.1 -proposed tracker (LP: #2000904) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: remove configs that are undefined across all + arches/flavours + - SAUCE: Revert "apparmor: make __aa_path_perm() static" + - [Packaging] abi-check: ignore failures when abi check is skipped + - [Packaging] temporarily disable zfs dkms + - [Config] update annotations after rebase to 6.2-rc1 + + [ Upstream Kernel Changes ] + + * Rebase to v6.1-rc1 + + -- Andrea Righi Wed, 04 Jan 2023 12:08:32 +0100 + +linux-unstable (6.2.0-0.0) lunar; urgency=medium + + * Empty entry + + -- Andrea Righi Sun, 01 Jan 2023 10:16:00 +0100 + +linux (6.1.0-11.11) lunar; urgency=medium + + * lunar/linux: 6.1.0-11.11 -proposed tracker (LP: #2000704) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * Lunar update: v6.1.1 upstream stable release (LP: #2000706) + - x86/vdso: Conditionally export __vdso_sgx_enter_enclave() + - libbpf: Fix uninitialized warning in btf_dump_dump_type_data + - PCI: mt7621: Add sentinel to quirks table + - mips: ralink: mt7621: define MT7621_SYSC_BASE with __iomem + - mips: ralink: mt7621: soc queries and tests as functions + - mips: ralink: mt7621: do not use kzalloc too early + - irqchip/ls-extirq: Fix endianness detection + - udf: Discard preallocation before extending file with a hole + - udf: Fix preallocation discarding at indirect extent boundary + - udf: Do not bother looking for prealloc extents if i_lenExtents matches + i_size + - udf: Fix extending file within last block + - usb: gadget: uvc: Prevent buffer overflow in setup handler + - USB: serial: option: add Quectel EM05-G modem + - USB: serial: cp210x: add Kamstrup RF sniffer PIDs + - USB: serial: f81232: fix division by zero on line-speed change + - USB: serial: f81534: fix division by zero on line-speed change + - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to ADL-N + - staging: r8188eu: fix led register settings + - igb: Initialize mailbox message for VF reset + - usb: typec: ucsi: Resume in separate work + - usb: dwc3: pci: Update PCIe device ID for USB3 controller on CPU sub-system + for Raptor Lake + - cifs: fix oops during encryption + - KEYS: encrypted: fix key instantiation with user-provided data + - Linux 6.1.1 + + * Expose built-in trusted and revoked certificates (LP: #1996892) + - [Packaging] Expose built-in trusted and revoked certificates + + * Fix System cannot detect bluetooth after running suspend stress test + (LP: #1998727) + - wifi: rtw88: 8821c: enable BT device recovery mechanism + + * Gnome doesn't run smooth when performing normal usage with RPL-P CPU + (LP: #1998419) + - drm/i915/rpl-p: Add stepping info + + * Mute/mic LEDs no function on a HP platfrom (LP: #1998882) + - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook + + * Add additional Mediatek MT7922 BT device ID (LP: #1998885) + - Bluetooth: btusb: Add a new VID/PID 0489/e0f2 for MT7922 + + * Support Icicle Kit reference design v2022.10 (LP: #1993148) + - SAUCE: riscv: dts: microchip: Disable PCIe on the Icicle Kit + + * Add iommu passthrough quirk for Intel IPU6 on RaptorLake (LP: #1989041) + - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs on Raptor + Lake + + * Enable Intel FM350 wwan CCCI driver port logging (LP: #1997686) + - net: wwan: t7xx: use union to group port type specific data + - net: wwan: t7xx: Add port for modem logging + + * TEE Support for CCP driver (LP: #1991608) + - crypto: ccp - Add support for TEE for PCI ID 0x14CA + + * Kinetic update: v5.19.17 upstream stable release (LP: #1994179) + - Revert "fs: check FMODE_LSEEK to control internal pipe splicing" + - kbuild: Add skip_encoding_btf_enum64 option to pahole + + * Kinetic update: v5.19.15 upstream stable release (LP: #1994078) + - Revert "clk: ti: Stop using legacy clkctrl names for omap4 and 5" + + * support independent clock and LED GPIOs for Intel IPU6 platforms + (LP: #1989046) + - SAUCE: platform/x86: int3472: support independent clock and LED GPIOs + + * Kernel livepatch support for for s390x (LP: #1639924) + - [Config] Enable EXPOLINE_EXTERN on s390x + + * Kinetic update: v5.19.7 upstream stable release (LP: #1988733) + - Revert "PCI/portdrv: Don't disable AER reporting in + get_port_device_capability()" + + * Kinetic update: v5.19.3 upstream stable release (LP: #1987345) + - Revert "mm: kfence: apply kmemleak_ignore_phys on early allocated pool" + + * Fix non-working e1000e device after resume (LP: #1951861) + - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit" + + * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004) + - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip + + * Fix system sleep on TGL systems with Intel ME (LP: #1919321) + - SAUCE: PCI: Serialize TGL e1000e PM ops + + * Fix broken e1000e device after S3 (LP: #1897755) + - SAUCE: e1000e: Increase polling timeout on MDIC ready bit + + * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312) + - SAUCE: USB: core: Make port power cycle a seperate helper function + - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state + + * Set explicit CC in the headers package (LP: #1999750) + - [Packaging] Set explicit CC in the headers package + + * commit cf58599cded35cf4affed1e659c0e2c742d3fda7 seems to be missing in + kinetic master to remove "hio" reference from Makefile (LP: #1999556) + - SAUCE: remove leftover reference to ubuntu/hio driver + + * Miscellaneous Ubuntu changes + - [Packaging] kernelconfig: always complete all config checks + - [Packaging] annotations: unify same rule across all flavour within the same + arch + - [Config] annotations: compact annotations file + - [Config] disable EFI_ZBOOT + - SAUCE: input: i8042: fix section mismatch warning + - debian/dkms-versions -- re-enable zfs + - [Packaging] old-kernelconfig: update config-check path + - [Packaging] update getabis + - [Packaging] update Ubuntu.md + + * Miscellaneous upstream changes + - Revert "drm/i915/opregion: check port number bounds for SWSCI display power + state" + + -- Andrea Righi Fri, 30 Dec 2022 11:23:16 +0100 + +linux (6.1.0-10.10) lunar; urgency=medium + + * lunar/linux: 6.1.0-10.10 -proposed tracker (LP: #1999569) + + * Soundwire support for the Intel RPL Gen platforms (LP: #1997944) + - ASoC: Intel: sof_sdw: Add support for SKU 0C10 product + - ASoC: Intel: soc-acpi: add SKU 0C10 SoundWire configuration + - ASoC: Intel: sof_sdw: Add support for SKU 0C40 product + - ASoC: Intel: soc-acpi: add SKU 0C40 SoundWire configuration + - ASoC: Intel: sof_sdw: Add support for SKU 0C4F product + - ASoC: rt1318: Add RT1318 SDCA vendor-specific driver + - ASoC: intel: sof_sdw: add rt1318 codec support. + - ASoC: Intel: sof_sdw: Add support for SKU 0C11 product + - ASoC: Intel: soc-acpi: add SKU 0C11 SoundWire configuration + - SAUCE: ASoC: Intel: soc-acpi: update codec addr on 0C11/0C4F product + - [Config] enable CONFIG_SND_SOC_RT1318_SDW + + * Virtual GPU driver packaging regression (LP: #1996112) + - [Packaging] Reintroduce VM DRM drivers into modules + + -- Andrea Righi Tue, 13 Dec 2022 22:14:08 +0100 + +linux (6.1.0-9.9) lunar; urgency=medium + + * Empty entry (ABI bump) + + -- Andrea Righi Tue, 13 Dec 2022 21:31:08 +0100 + +linux (6.1.0-3.3) lunar; urgency=medium + + * lunar/linux: 6.1.0-3.3 -proposed tracker (LP: #1999534) + + * [DEP-8] Run ADT regression suite for lowlatency kernels Jammy and later + (LP: #1999528) + - [DEP-8] Fix regression suite to run on lowlatency + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: do not add constraints on toolchain versions + + -- Andrea Righi Tue, 13 Dec 2022 16:45:59 +0100 + +linux (6.1.0-2.2) lunar; urgency=medium + + * lunar/linux: 6.1.0-2.2 -proposed tracker (LP: #1999411) + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: do not enforce toolchain versions + + -- Andrea Righi Mon, 12 Dec 2022 17:05:59 +0100 + +linux (6.1.0-1.1) lunar; urgency=medium + + * lunar/linux: 6.1.0-1.1 -proposed tracker (LP: #1999373) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + + * Miscellaneous Ubuntu changes + - [Packaging] annotations: set and delete configs from command line + - [Packaging] migrateconfigs: ignore README.rst if it doesn't exist + - [Packaging] migrate-annotations: properly determine arches in derivatives + - [Packaging] annotations: allow to set note to config options directly + - [Packaging] annotations: assume --query as default command + - [Packaging] annotations: allow to query using CONFIG_" +[Unit] +Description=Hyper-V KVP Protocol Daemon +ConditionVirtualization=microsoft +ConditionKernelCommandLine=!snapd_recovery_mode +DefaultDependencies=no +BindsTo=sys-devices-virtual-misc-vmbus\x21hv_kvp.device +After=sys-devices-virtual-misc-vmbus\x21hv_kvp.device systemd-remount-fs.service +Before=shutdown.target cloud-init-local.service walinuxagent.service +Conflicts=shutdown.target +RequiresMountsFor=/var/lib/hyperv + +[Service] +ExecStart=/usr/sbin/hv_kvp_daemon -n + +[Install] +WantedBy=multi-user.target --- linux-xilinx-6.8.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.udev +++ linux-xilinx-6.8.0/debian/linux-cloud-tools-common.hv-kvp-daemon.udev @@ -0,0 +1 @@ +SUBSYSTEM=="misc", KERNEL=="vmbus/hv_kvp", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-kvp-daemon.service" --- linux-xilinx-6.8.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.upstart +++ linux-xilinx-6.8.0/debian/linux-cloud-tools-common.hv-kvp-daemon.upstart @@ -0,0 +1,22 @@ +# On Azure/Hyper-V systems start the hv_kvp_daemon +# +description "Hyper-V KVP Protocol Daemon" +author "Adam Conrad " + +start on runlevel [2345] +stop on runlevel [!2345] +console log + +pre-start script + if [ -e "/etc/default/hv-kvp-daemon-init" ]; then + . /etc/default/hv-kvp-daemon-init + fi + [ "$RUN_KVP_DAEMON" = 0 ] && { stop; exit 0; } + if [ -d /sys/class/dmi/id/. ]; then + read company " +[Unit] +Description=Hyper-V VSS Protocol Daemon +ConditionVirtualization=microsoft +ConditionPathExists=/dev/vmbus/hv_vss +BindsTo=sys-devices-virtual-misc-vmbus\x21hv_vss.device + +[Service] +ExecStart=/usr/sbin/hv_vss_daemon -n + +[Install] +WantedBy=multi-user.target --- linux-xilinx-6.8.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.udev +++ linux-xilinx-6.8.0/debian/linux-cloud-tools-common.hv-vss-daemon.udev @@ -0,0 +1 @@ +SUBSYSTEM=="misc", KERNEL=="vmbus/hv_vss", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-vss-daemon.service" --- linux-xilinx-6.8.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.upstart +++ linux-xilinx-6.8.0/debian/linux-cloud-tools-common.hv-vss-daemon.upstart @@ -0,0 +1,22 @@ +# On Azure/Hyper-V systems start the hv_vss_daemon +# +description "Hyper-V VSS Protocol Daemon" +author "Ben Howard " + +start on runlevel [2345] +stop on runlevel [!2345] +console log + +pre-start script + if [ -e "/etc/default/hv-kvp-daemon-init" ]; then + . /etc/default/hv-kvp-daemon-init + fi + [ "$RUN_VSS_DAEMON" -eq 0 ] && { stop; exit 0; } + if [ -d /sys/class/dmi/id/. ]; then + read company +# + +# Do not use make's built-in rules and variables +# (this increases performance and avoids hard-to-debug behaviour) +MAKEFLAGS += -rR + +# Allow to run debian/rules directly without root +export DEB_RULES_REQUIRES_ROOT := no + +.NOTPARALLEL: + +DEBIAN=$(shell awk -F= '($$1 == "DEBIAN") { print $$2 }' $(DEBIAN)/control.stub; + flavours="$(sort $(wildcard $(DEBIAN)/control.d/vars.*))";\ + for i in $$flavours; do \ + $(SHELL) $(DROOT)/scripts/control-create $$i "$(any_signed)" | \ + sed -e 's/PKGVER/$(release)/g' \ + -e 's/ABINUM/$(abinum)/g' \ + -e 's/SRCPKGNAME/$(src_pkg_name)/g' \ + -e 's/=HUMAN=/$(human_arch)/g' \ + -e 's/=SERIES=/$(series)/g' \ + >> $(DEBIAN)/control.stub; \ + done + +.PHONY: debian/control +debian/control: $(DEBIAN)/control.stub + cp $(DEBIAN)/control.stub debian/control + +debian/canonical-certs.pem: $(wildcard $(DROOT)/certs/*-all.pem) $(wildcard $(DROOT)/certs/*-$(arch).pem) $(wildcard $(DEBIAN)/certs/*-all.pem) $(wildcard $(DEBIAN)/certs/*-$(arch).pem) + for cert in $(sort $(notdir $^)); \ + do \ + for dir in $(DEBIAN) $(DROOT); \ + do \ + if [ -f "$$dir/certs/$$cert" ]; then \ + cat "$$dir/certs/$$cert"; \ + break; \ + fi; \ + done; \ + done >"$@" + +debian/canonical-revoked-certs.pem: $(wildcard $(DROOT)/revoked-certs/*-all.pem) $(wildcard $(DROOT)/revoked-certs/*-$(arch).pem) $(wildcard $(DEBIAN)/revoked-certs/*-all.pem) $(wildcard $(DEBIAN)/revoked-certs/*-$(arch).pem) + for cert in $(sort $(notdir $^)); \ + do \ + for dir in $(DEBIAN) $(DROOT); \ + do \ + if [ -f "$$dir/revoked-certs/$$cert" ]; then \ + cat "$$dir/revoked-certs/$$cert"; \ + break; \ + fi; \ + done; \ + done >"$@" --- linux-xilinx-6.8.0.orig/debian/rules.d/0-common-vars.mk +++ linux-xilinx-6.8.0/debian/rules.d/0-common-vars.mk @@ -0,0 +1,269 @@ +# Used when you need to 'escape' a comma. +comma = , +empty := +space := $(empty) $(empty) + +# +# The source package name will be the first token from $(DEBIAN)/changelog +# +src_pkg_name := $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -S source) + +# Get the series +series := $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -S distribution | sed -e 's/-\(security\|updates\|proposed\)$$//') + +# Get some version info +version := $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -S version) +revision ?= $(lastword $(subst -,$(space),$(version))) +release := $(patsubst %-$(revision),%,$(version)) + +prev_fullver ?= $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -o1 -c1 -S version) +prev_revision := $(lastword 0.0 $(subst -,$(space),$(prev_fullver))) + +# Get upstream version info +upstream_version := $(shell sed -n 's/^VERSION = \(.*\)$$/\1/p' Makefile) +upstream_patchlevel := $(shell sed -n 's/^PATCHLEVEL = \(.*\)$$/\1/p' Makefile) +upstream_tag := "v$(upstream_version).$(upstream_patchlevel)" + +# Get the kernels own extra version to be added to the release signature. +raw_kernelversion=$(shell make kernelversion) + +packages_enabled := $(shell dh_listpackages 2>/dev/null) +define if_package +$(if $(filter $(1),$(packages_enabled)),$(2)) +endef + +stamp = [ -d $(dir $@) ] || mkdir $(dir $@); touch $@ + +# +# do_full_build -- are we doing a full buildd style build, i.e., are we +# building in a PPA +# +ifeq ($(wildcard /CurrentlyBuilding),) + do_full_build ?= false +else + do_full_build ?= true +endif + +# +# The debug packages are ginormous, so you probably want to skip +# building them (as a developer). +# +do_dbgsym_package = true +ifeq ($(do_full_build),false) + do_dbgsym_package = false +endif +ifeq ($(filter $(DEB_BUILD_OPTIONS),noautodbgsym),noautodbgsym) + # Disable debug package builds if we're building in a PPA that has the + # 'Build debug symbols' option disabled + do_dbgsym_package = false +endif + +abinum := $(firstword $(subst .,$(space),$(revision))) +prev_abinum := $(firstword $(subst .,$(space),$(prev_revision))) +abi_release := $(release)-$(abinum) + +uploadnum := $(patsubst $(abinum).%,%,$(revision)) +ifneq ($(do_full_build),false) + uploadnum := $(uploadnum)-Ubuntu +endif + +DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_HOST_GNU_TYPE = $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE = $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_HOST_ARCH = $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH) + +# +# Detect invocations of the form 'fakeroot debian/rules binary arch=armhf' +# within an x86'en schroot. This only gets you part of the way since the +# packaging phase fails, but you can at least compile the kernel quickly. +# +arch := $(DEB_HOST_ARCH) +CROSS_COMPILE ?= $(DEB_HOST_GNU_TYPE)- + +# +# Set consistent toolchain +# If a given kernel wants to change this, they can do so via their own +# $(DEBIAN)/rules.d/hooks.mk and $(DEBIAN)/rules.d/$(arch).mk files +# +export gcc?=gcc-13 +GCC_BUILD_DEPENDS=\ $(gcc), $(gcc)-aarch64-linux-gnu [arm64] , $(gcc)-arm-linux-gnueabihf [armhf] , $(gcc)-powerpc64le-linux-gnu [ppc64el] , $(gcc)-riscv64-linux-gnu [riscv64] , $(gcc)-s390x-linux-gnu [s390x] , $(gcc)-x86-64-linux-gnu [amd64] , + +abidir := $(CURDIR)/$(DEBIAN)/__abi.current/$(arch) +commonconfdir := $(CURDIR)/$(DEBIAN)/config +archconfdir := $(CURDIR)/$(DEBIAN)/config/$(arch) +sharedconfdir := $(CURDIR)/debian.master/config +builddir := $(CURDIR)/debian/build +stampdir := $(CURDIR)/debian/stamps + +# +# The binary package name always starts with linux-image-$KVER-$ABI.$UPLOAD_NUM. There +# are places that you'll find linux-image hard coded, but I guess thats OK since the +# assumption that the binary package always starts with linux-image will never change. +# +bin_pkg_name_signed=linux-image-$(abi_release) +bin_pkg_name_unsigned=linux-image-unsigned-$(abi_release) +mods_pkg_name=linux-modules-$(abi_release) +mods_extra_pkg_name=linux-modules-extra-$(abi_release) +bldinfo_pkg_name=linux-buildinfo-$(abi_release) +hdrs_pkg_name=linux-headers-$(abi_release) +rust_pkg_name=$(src_pkg_name)-lib-rust-$(abi_release) +indep_hdrs_pkg_name=$(src_pkg_name)-headers-$(abi_release) +indep_lib_rust_pkg_name=$(src_pkg_name)-lib-rust-$(abi_release) + +# +# Similarly with the linux-source package, you need not build it as a developer. Its +# somewhat I/O intensive and utterly useless. +# +do_source_package=true +do_source_package_content=true +ifeq ($(do_full_build),false) +do_source_package_content=false +endif + +# common headers normally is built as an indep package, but may be arch +do_common_headers_indep=true + +# build tools +ifneq ($(wildcard $(CURDIR)/tools),) + ifeq ($(do_tools),) + ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) + do_tools=false + endif + endif + do_tools?=true +else + do_tools?=false +endif +tools_pkg_name=$(src_pkg_name)-tools-$(abi_release) +tools_common_pkg_name=linux-tools-common +tools_flavour_pkg_name=linux-tools-$(abi_release) +cloud_pkg_name=$(src_pkg_name)-cloud-tools-$(abi_release) +cloud_common_pkg_name=linux-cloud-tools-common +cloud_flavour_pkg_name=linux-cloud-tools-$(abi_release) +hosttools_pkg_name=linux-tools-host + +# The general flavour specific image package. +do_flavour_image_package=true + +# The general flavour specific header package. +do_flavour_header_package=true + +# DTBs +do_dtbs=false + +# ZSTD compressed kernel modules +do_zstd_ko=true +ifeq ($(series),jammy) +do_zstd_ko= +endif + +# Support parallel= in DEB_BUILD_OPTIONS (see #209008) +# +# These 2 environment variables set the -j value of the kernel build. For example, +# CONCURRENCY_LEVEL=16 fakeroot $(DEBIAN)/rules binary-debs +# or +# DEB_BUILD_OPTIONS=parallel=16 fakeroot $(DEBIAN)/rules binary-debs +# +# The default is to use the number of CPUs. +# +COMMA=, +DEB_BUILD_OPTIONS_PARA = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) +ifneq (,$(DEB_BUILD_OPTIONS_PARA)) + CONCURRENCY_LEVEL := $(DEB_BUILD_OPTIONS_PARA) +endif + +ifeq ($(CONCURRENCY_LEVEL),) + # Check the environment + CONCURRENCY_LEVEL := $(shell echo $$CONCURRENCY_LEVEL) + # No? Then build with the number of CPUs on the host. + ifeq ($(CONCURRENCY_LEVEL),) + CONCURRENCY_LEVEL := $(shell expr `getconf _NPROCESSORS_ONLN` \* 1) + endif + # Oh hell, give 'em one + ifeq ($(CONCURRENCY_LEVEL),) + CONCURRENCY_LEVEL := 1 + endif +endif + +conc_level = -j$(CONCURRENCY_LEVEL) + +PYTHON ?= $(firstword $(wildcard /usr/bin/python3) $(wildcard /usr/bin/python2) $(wildcard /usr/bin/python)) + +HOSTCC ?= $(DEB_BUILD_GNU_TYPE)-$(gcc) + +# target_flavour is filled in for each step +kmake = make ARCH=$(build_arch) \ + CROSS_COMPILE=$(CROSS_COMPILE) \ + HOSTCC=$(HOSTCC) \ + CC=$(CROSS_COMPILE)$(gcc) \ + BINDGEN=bindgen-0.65 \ + KERNELRELEASE=$(abi_release)-$(target_flavour) \ + CONFIG_DEBUG_SECTION_MISMATCH=y \ + KBUILD_BUILD_VERSION="$(uploadnum)" \ + CFLAGS_MODULE="-DPKG_ABI=$(abinum)" \ + PYTHON=$(PYTHON) +ifneq ($(LOCAL_ENV_CC),) +kmake += CC="$(LOCAL_ENV_CC)" DISTCC_HOSTS="$(LOCAL_ENV_DISTCC_HOSTS)" +endif + +# Locking is required in parallel builds to prevent loss of contents +# of the debian/files. +lockme = flock -w 60 $(CURDIR)/debian/.LOCK + +# Don't fail if a link already exists. +LN = ln -sf + +# Checks if a var is overriden by the custom rules. Called with var and +# flavour as arguments. +custom_override = $(or $($(1)_$(2)),$($(1))) + +# selftests that Ubuntu cares about +ubuntu_selftests = breakpoints cpu-hotplug efivarfs memfd memory-hotplug mount net ptrace seccomp timers powerpc user ftrace + +# DKMS +all_dkms_modules = + +subst_paired = $(subst $(firstword $(subst =, ,$(1))),$(lastword $(subst =, ,$(1))),$(2)) +recursive_call = $(if $(2),$(call recursive_call,$(1),$(wordlist 2,$(words $(2)),$(2)),$(call $(1),$(firstword $(2)),$(3))),$(3)) + +$(foreach _line,$(shell gawk '{ OFS = "!"; $$1 = $$1; print }' $(DEBIAN)/dkms-versions), \ + $(eval _params = $(subst !, ,$(_line))) \ + $(eval _deb_pkgname = $(firstword $(_params))) \ + $(eval _deb_version = $(word 2,$(_params))) \ + $(if $(filter modulename=%,$(_params)), \ + $(eval _m = $(word 2,$(subst =, ,$(filter modulename=%,$(_params))))) \ + , \ + $(info modulename for $(_deb_pkgname) not specified in dkms-versions. Assume $(_deb_pkgname).) \ + $(eval _m = $(_deb_pkgname)) \ + ) \ + $(eval all_dkms_modules += $(_m)) \ + $(eval dkms_$(_m)_version = $(_deb_version)) \ + $(foreach _p,$(patsubst debpath=%,%,$(filter debpath=%,$(_params))), \ + $(eval dkms_$(_m)_debpath += $(strip \ + $(call recursive_call,subst_paired, \ + %module%=$(_m) \ + %package%=$(_deb_pkgname) \ + %version%=$(lastword $(subst :, ,$(_deb_version))) \ + , \ + $(_p) \ + ) \ + )) \ + ) \ + $(if $(dkms_$(_m)_debpath),,$(error debpath for $(_deb_pkgname) not specified.)) \ + $(if $(filter arch=%,$(_params)), \ + $(eval dkms_$(_m)_archs = $(patsubst arch=%,%,$(filter arch=%,$(_params)))) \ + , \ + $(eval dkms_$(_m)_archs = any) \ + ) \ + $(eval dkms_$(_m)_rprovides = $(patsubst rprovides=%,%,$(filter rprovides=%,$(_params)))) \ + $(eval dkms_$(_m)_type = $(word 1,$(patsubst type=%,%,$(filter type=%,$(_params))) built-in)) \ + $(eval all_$(dkms_$(_m)_type)_dkms_modules += $(_m)) \ + $(if $(filter standalone,$(dkms_$(_m)_type)), \ + $(eval dkms_$(_m)_pkg_name = linux-modules-$(_m)-$(abi_release)) \ + $(eval dkms_$(_m)_subdir = ubuntu) \ + , \ + $(eval dkms_$(_m)_pkg_name = $(mods_pkg_name)) \ + $(eval dkms_$(_m)_subdir = kernel) \ + ) \ +) --- linux-xilinx-6.8.0.orig/debian/rules.d/1-maintainer.mk +++ linux-xilinx-6.8.0/debian/rules.d/1-maintainer.mk @@ -0,0 +1,135 @@ +# The following targets are for the maintainer only! do not run if you don't +# know what they do. + +.PHONY: help +help: + @echo "These are the targets in addition to the normal $(DEBIAN) ones:" + @echo + @echo " printenv : Print some variables used in the build" + @echo " updateconfigs : Update core arch configs" + @echo " defaultconfigs : Update core arch configs using defaults" + @echo " genconfigs : Generate core arch configs in CONFIGS/*" + @echo " editconfigs : Edit core arch configs" + @echo " printchanges : Print the current changelog entries (from git)" + @echo " insertchanges : Insert current changelog entries (from git)" + @echo " compileselftests : Only compile the selftests listed on ubuntu_selftests variable" + @echo " runselftests : Run the selftests listed on ubuntu_selftests variable" + @echo + @echo "Environment variables:" + @echo + @echo " CONCURRENCY_LEVEL=X : Use -jX for kernel compile" + +.PHONY: printdebian +printdebian: + @echo "$(DEBIAN)" + +configs-targets := updateconfigs defaultconfigs genconfigs editconfigs + +.PHONY: $(configs-targets) +$(configs-targets): + dh_testdir + kmake='$(kmake)' skip_checks=$(do_skip_checks) conc_level=$(conc_level) \ + $(SHELL) $(DROOT)/scripts/misc/kernelconfig $@ + +.PHONY: printenv +printenv: + @dh_testdir + @echo "src_pkg_name = $(src_pkg_name)" + @echo "series = $(series)" + @echo "release = $(release)" + @echo "revision = $(revision)" + @echo "uploadnum = $(uploadnum)" + @echo "prev_revision = $(prev_revision)" + @echo "abinum = $(abinum)" + @echo "upstream_tag = $(upstream_tag)" + @echo "flavours = $(flavours)" + @echo "bin_pkg_name = $(bin_pkg_name)" + @echo "hdr_pkg_name = $(hdrs_pkg_name)" + @echo "rust_pkg_name = $(rust_pkg_name)" + @echo "ubuntu_selftests = $(ubuntu_selftests)" + @echo "arch = $(arch)" + @echo "kmake = $(kmake)" + @echo + @echo "CONCURRENCY_LEVEL = $(CONCURRENCY_LEVEL)" + @echo "DEB_HOST_GNU_TYPE = $(DEB_HOST_GNU_TYPE)" + @echo "DEB_BUILD_GNU_TYPE = $(DEB_BUILD_GNU_TYPE)" + @echo "DEB_HOST_ARCH = $(DEB_HOST_ARCH)" + @echo "DEB_BUILD_ARCH = $(DEB_BUILD_ARCH)" + @echo + @echo "any_signed = $(any_signed)" + @echo " uefi_signed = $(uefi_signed)" + @echo " opal_signed = $(opal_signed)" + @echo " sipl_signed = $(sipl_signed)" + @echo + @echo "do_skip_checks = $(do_skip_checks)" + @echo "do_full_build = $(do_full_build)" + @echo "do_mainline_build = $(do_mainline_build)" + @echo "do_dbgsym_package = $(do_dbgsym_package)" + @echo "do_dtbs = $(do_dtbs)" + @echo "do_source_package = $(do_source_package)" + @echo "do_source_package_content = $(do_source_package_content)" + @echo "do_extras_package = $(do_extras_package)" + @echo "do_flavour_image_package = $(do_flavour_image_package)" + @echo "do_flavour_header_package = $(do_flavour_header_package)" + @echo "do_common_headers_indep = $(do_common_headers_indep)" + @echo "do_lib_rust = $(do_lib_rust)" + @echo "do_tools = $(do_tools)" + @echo "do_tools_common = $(do_tools_common)" + @echo "do_any_tools = $(do_any_tools)" + @echo "do_linux_tools = $(do_linux_tools)" + @echo " do_tools_acpidbg = $(do_tools_acpidbg)" + @echo " do_tools_bpftool = $(do_tools_bpftool)" + @echo " do_tools_cpupower = $(do_tools_cpupower)" + @echo " do_tools_host = $(do_tools_host)" + @echo " do_tools_perf = $(do_tools_perf)" + @echo " do_tools_perf_jvmti = $(do_tools_perf_jvmti)" + @echo " do_tools_perf_python = $(do_tools_perf_python)" + @echo " do_tools_usbip = $(do_tools_usbip)" + @echo " do_tools_x86 = $(do_tools_x86)" + @echo "do_cloud_tools = $(do_cloud_tools)" + @echo " do_tools_hyperv = $(do_tools_hyperv)" + @echo + @echo "all_dkms_modules = $(all_dkms_modules)" + @$(foreach mod,$(all_dkms_modules),$(foreach var,$(do_$(mod)),\ + printf " %-24s = %s\n" "do_$(mod)" "$(var)";)) + +.PHONY: printchanges +printchanges: + @baseCommit=$$(git log --pretty=format:'%H %s' | \ + gawk '/UBUNTU: '".*Ubuntu-.*`echo $(prev_fullver) | sed 's/+/\\\\+/'`"'(~.*)?$$/ { print $$1; exit }'); \ + if [ -z "$$baseCommit" ]; then \ + echo "WARNING: couldn't find a commit for the previous version. Using the lastest one." >&2; \ + baseCommit=$$(git log --pretty=format:'%H %s' | \ + gawk '/UBUNTU:\s*Ubuntu-.*$$/ { print $$1; exit }'); \ + fi; \ + git log "$$baseCommit"..HEAD | \ + $(DROOT)/scripts/misc/git-ubuntu-log + +.PHONY: insertchanges +insertchanges: autoreconstruct finalchecks + $(DROOT)/scripts/misc/insert-changes $(DROOT) $(DEBIAN) + +.PHONY: autoreconstruct +autoreconstruct: + # No need for reconstruct for -rc kernels since we don't upload an + # orig tarball, so just remove it. + if grep -q "^EXTRAVERSION = -rc[0-9]\+$$" Makefile; then \ + echo "exit 0" >$(DEBIAN)/reconstruct; \ + else \ + $(DROOT)/scripts/misc/gen-auto-reconstruct $(upstream_tag) $(DEBIAN)/reconstruct $(DROOT)/source/options; \ + fi + +.PHONY: finalchecks +finalchecks: debian/control + $(DROOT)/scripts/checks/final-checks "$(DEBIAN)" "$(prev_fullver)" $(do_skip_checks) + +.PHONY: compileselftests +compileselftests: + # a loop is needed here to fail on errors + for test in $(ubuntu_selftests); do \ + $(kmake) -C tools/testing/selftests TARGETS="$$test"; \ + done; + +.PHONY: runselftests +runselftests: + $(kmake) -C tools/testing/selftests TARGETS="$(ubuntu_selftests)" run_tests --- linux-xilinx-6.8.0.orig/debian/rules.d/2-binary-arch.mk +++ linux-xilinx-6.8.0/debian/rules.d/2-binary-arch.mk @@ -0,0 +1,771 @@ +# We don't want make removing intermediary stamps +.SECONDARY : + +# TODO this is probably wrong, and should be using $(DEB_HOST_MULTIARCH) +shlibdeps_opts = $(if $(CROSS_COMPILE),-- -l$(CROSS_COMPILE:%-=/usr/%)/lib) + +debian/scripts/fix-filenames: debian/scripts/fix-filenames.c + $(HOSTCC) $^ -o $@ + +$(stampdir)/stamp-prepare-%: config-prepare-check-% + @echo Debug: $@ + $(stamp) + +$(stampdir)/stamp-prepare-tree-%: target_flavour = $* +$(stampdir)/stamp-prepare-tree-%: debian/scripts/fix-filenames + @echo Debug: $@ + install -d $(builddir)/build-$* + touch $(builddir)/build-$*/ubuntu-build + python3 debian/scripts/misc/annotations --export --arch $(arch) --flavour $(target_flavour) > $(builddir)/build-$*/.config + sed -i 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$* $(raw_kernelversion)"/' $(builddir)/build-$*/.config + find $(builddir)/build-$* -name "*.ko" | xargs rm -f + $(kmake) O=$(builddir)/build-$* $(conc_level) rustavailable || true + $(kmake) O=$(builddir)/build-$* $(conc_level) olddefconfig + $(stamp) + +# Used by developers as a shortcut to prepare a tree for compilation. +prepare-%: $(stampdir)/stamp-prepare-% + @echo Debug: $@ +# Used by developers to allow efficient pre-building without fakeroot. +build-%: $(stampdir)/stamp-install-% + @echo Debug: $@ + +# Do the actual build, including image and modules +$(stampdir)/stamp-build-%: target_flavour = $* +$(stampdir)/stamp-build-%: bldimg = $(call custom_override,build_image,$*) +$(stampdir)/stamp-build-%: $(stampdir)/stamp-prepare-% + @echo Debug: $@ build_image $(build_image) bldimg $(bldimg) + $(kmake) O=$(builddir)/build-$* $(conc_level) $(bldimg) modules $(if $(filter true,$(do_dtbs)),dtbs) + +ifeq ($(do_dbgsym_package),true) + # The target scripts_gdb is part of "all", so we need to call it manually + if grep -q CONFIG_GDB_SCRIPTS=y $(builddir)/build-$*/.config; then \ + $(kmake) O=$(builddir)/build-$* $(conc_level) scripts_gdb ; \ + fi +endif + $(stamp) + +define build_dkms_sign = + $(shell set -x; if grep -q CONFIG_MODULE_SIG=y $(1)/.config; then + echo $(1)/scripts/sign-file $(MODHASHALGO) $(MODSECKEY) $(MODPUBKEY); + else + echo "-"; + fi + ) +endef +define build_dkms = + rc=0; unset MAKEFLAGS; ARCH=$(build_arch) CROSS_COMPILE=$(CROSS_COMPILE) $(SHELL) $(DROOT)/scripts/dkms-build $(dkms_dir) $(abi_release)-$* '$(call build_dkms_sign,$(builddir)/build-$*)' $(1) $(2) $(3) $(4) $(5) || rc=$$?; if [ "$$rc" = "9" -o "$$rc" = "77" ]; then echo do_$(4)_$*=false >> $(builddir)/skipped-dkms.mk; rc=0; fi; if [ "$$rc" != "0" ]; then exit $$rc; fi +endef + +define install_control = + for which in $(3); \ + do \ + template="$(DROOT)/templates/$(2).$$which.in"; \ + script="$(DROOT)/$(1).$$which"; \ + sed -e 's/@abiname@/$(abi_release)/g' \ + -e 's/@localversion@/-$*/g' \ + -e 's/@image-stem@/$(instfile)/g' \ + <"$$template" >"$$script"; \ + done +endef + +# Ensure the directory prefix is exactly 140 characters long so pathnames are the +# exact same length in any binary files produced by the builds. These will be +# commonised later. +dkms_20d=.................... +dkms_140d=$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d) +dkms_140c=$(shell echo '$(dkms_140d)' | sed -e 's/\./_/g') +define dkms_dir_prefix = +$(shell echo $(1)/$(dkms_140c) | \ + sed -e 's/\($(dkms_140d)\).*/\1/' -e 's/^\(.*\)....$$/\1dkms/') +endef + +# Install the finished build +$(stampdir)/stamp-install-%: pkgdir_bin = $(CURDIR)/debian/$(bin_pkg_name)-$* +$(stampdir)/stamp-install-%: pkgdir = $(CURDIR)/debian/$(mods_pkg_name)-$* +$(stampdir)/stamp-install-%: pkgdir_ex = $(CURDIR)/debian/$(mods_extra_pkg_name)-$* +$(stampdir)/stamp-install-%: pkgdir_bldinfo = $(CURDIR)/debian/$(bldinfo_pkg_name)-$* +$(stampdir)/stamp-install-%: bindoc = $(pkgdir)/usr/share/doc/$(bin_pkg_name)-$* +$(stampdir)/stamp-install-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym +$(stampdir)/stamp-install-%: signingv = $(CURDIR)/debian/$(bin_pkg_name)-signing/$(release)-$(revision) +$(stampdir)/stamp-install-%: toolspkgdir = $(CURDIR)/debian/$(tools_flavour_pkg_name)-$* +$(stampdir)/stamp-install-%: cloudpkgdir = $(CURDIR)/debian/$(cloud_flavour_pkg_name)-$* +$(stampdir)/stamp-install-%: basepkg = $(hdrs_pkg_name) +$(stampdir)/stamp-install-%: baserustpkg = $(rust_pkg_name) +$(stampdir)/stamp-install-%: indeppkg = $(indep_hdrs_pkg_name) +$(stampdir)/stamp-install-%: kernfile = $(call custom_override,kernel_file,$*) +$(stampdir)/stamp-install-%: instfile = $(call custom_override,install_file,$*) +$(stampdir)/stamp-install-%: hdrdir = $(CURDIR)/debian/$(basepkg)-$*/usr/src/$(basepkg)-$* +$(stampdir)/stamp-install-%: rustdir = $(CURDIR)/debian/$(baserustpkg)-$*/usr/src/$(baserustpkg)-$* +$(stampdir)/stamp-install-%: target_flavour = $* +$(stampdir)/stamp-install-%: MODHASHALGO=sha512 +$(stampdir)/stamp-install-%: MODSECKEY=$(builddir)/build-$*/certs/signing_key.pem +$(stampdir)/stamp-install-%: MODPUBKEY=$(builddir)/build-$*/certs/signing_key.x509 +$(stampdir)/stamp-install-%: build_dir=$(builddir)/build-$* +$(stampdir)/stamp-install-%: dkms_dir=$(call dkms_dir_prefix,$(builddir)/build-$*) +$(foreach _m,$(all_dkms_modules), \ + $(eval $$(stampdir)/stamp-install-%: enable_$(_m) = $$(filter true,$$(call custom_override,do_$(_m),$$*))) \ + $(eval $$(stampdir)/stamp-install-%: dkms_$(_m)_pkgdir = $$(CURDIR)/debian/$(dkms_$(_m)_pkg_name)-$$*) \ +) +$(stampdir)/stamp-install-%: dbgpkgdir_dkms = $(if $(filter true,$(do_dbgsym_package)),$(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/kernel,"") +$(stampdir)/stamp-install-%: $(stampdir)/stamp-build-% $(stampdir)/stamp-install-headers + @echo Debug: $@ kernel_file $(kernel_file) kernfile $(kernfile) install_file $(install_file) instfile $(instfile) + dh_testdir + dh_prep -p$(bin_pkg_name)-$* + dh_prep -p$(mods_pkg_name)-$* + dh_prep -p$(hdrs_pkg_name)-$* +ifeq ($(do_lib_rust),true) + dh_prep -p$(rust_pkg_name)-$* +endif + $(foreach _m,$(all_standalone_dkms_modules), \ + $(if $(enable_$(_m)),dh_prep -p$(dkms_$(_m)_pkg_name)-$*;)\ + ) +ifeq ($(do_dbgsym_package),true) + dh_prep -p$(bin_pkg_name)-$*-dbgsym +endif +ifeq ($(do_extras_package),true) + dh_prep -p$(mods_extra_pkg_name)-$* +endif + + # The main image + # compress_file logic required because not all architectures + # generate a zImage automatically out of the box +ifeq ($(compress_file),) + install -m600 -D $(builddir)/build-$*/$(kernfile) \ + $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* +else + install -d $(pkgdir_bin)/boot + gzip -c9v $(builddir)/build-$*/$(kernfile) > \ + $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* + chmod 600 $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* +endif + install -d $(pkgdir)/boot + install -m644 $(builddir)/build-$*/.config \ + $(pkgdir)/boot/config-$(abi_release)-$* + install -m600 $(builddir)/build-$*/System.map \ + $(pkgdir)/boot/System.map-$(abi_release)-$* + +ifeq ($(do_dtbs),true) + $(kmake) O=$(builddir)/build-$* $(conc_level) dtbs_install \ + INSTALL_DTBS_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$*/device-tree +endif + +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux + chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* +endif + + $(kmake) O=$(builddir)/build-$* $(conc_level) modules_install $(vdso) \ + INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$(pkgdir) + + # + # Build module blacklists: + # - blacklist all watchdog drivers (LP:1432837) + # + install -d $(pkgdir)/lib/modprobe.d + echo "# Kernel supplied blacklist for $(src_pkg_name) $(abi_release)-$* $(arch)" \ + >$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + for conf in $(arch)-$* $(arch) common.conf; do \ + if [ -f $(DEBIAN)/modprobe.d/$$conf ]; then \ + echo "# modprobe.d/$$conf"; \ + cat $(DEBIAN)/modprobe.d/$$conf; \ + fi; \ + done >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + echo "# Autogenerated watchdog blacklist" \ + >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + ls -1 $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/watchdog/ | \ + grep -v '^bcm2835_wdt$$' | \ + sed -e 's/^/blacklist /' -e 's/.ko$$//' | \ + sort -u \ + >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + +ifeq ($(do_extras_package),true) + # + # Remove all modules not in the inclusion list. + # + if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \ + /sbin/depmod -v -b $(pkgdir) $(abi_release)-$* | \ + sed -e "s@$(pkgdir)/lib/modules/$(abi_release)-$*/kernel/@@g" | \ + awk '{ print $$1 " " $$NF}' >$(build_dir)/module-inclusion.depmap; \ + mkdir -p $(pkgdir_ex)/lib/modules/$(abi_release)-$*; \ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/kernel \ + $(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel; \ + $(SHELL) $(DROOT)/scripts/module-inclusion --master \ + $(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel \ + $(pkgdir)/lib/modules/$(abi_release)-$*/kernel \ + $(DEBIAN)/control.d/$(target_flavour).inclusion-list \ + $(build_dir)/module-inclusion.depmap 2>&1 | \ + tee $(target_flavour).inclusion-list.log; \ + /sbin/depmod -b $(pkgdir) -ea -F $(pkgdir)/boot/System.map-$(abi_release)-$* \ + $(abi_release)-$* 2>&1 |tee $(target_flavour).depmod.log; \ + if [ `grep -c 'unknown symbol' $(target_flavour).depmod.log` -gt 0 ]; then \ + echo "EE: Unresolved module dependencies in base package!"; \ + exit 1; \ + fi \ + fi +endif + +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux + chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* +endif + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/build + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/source + + # Some initramfs-tools specific modules + install -d $(pkgdir)/lib/modules/$(abi_release)-$*/initrd + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko ]; then\ + $(LN) $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko \ + $(pkgdir)/lib/modules/$(abi_release)-$*/initrd/; \ + fi + + echo "interest linux-update-$(abi_release)-$*" >"$(DROOT)/$(bin_pkg_name)-$*.triggers" + install -d $(pkgdir_bin)/usr/lib/linux/triggers + $(call install_control,$(bin_pkg_name)-$*,image,postinst postrm preinst prerm) + install -d $(pkgdir)/usr/lib/linux/triggers + $(call install_control,$(mods_pkg_name)-$*,extra,postinst postrm) +ifeq ($(do_extras_package),true) + # Install the postinit/postrm scripts in the extras package. + if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \ + install -d $(pkgdir_ex)/usr/lib/linux/triggers; \ + $(call install_control,$(mods_extra_pkg_name)-$*,extra,postinst postrm); \ + fi +endif + $(foreach _m,$(all_standalone_dkms_modules), \ + $(if $(enable_$(_m)), \ + install -d $(dkms_$(_m)_pkgdir)/usr/lib/linux/triggers; \ + $(call install_control,$(dkms_$(_m)_pkg_name)-$*,extra,postinst postrm); \ + ) \ + ) + +ifeq ($(do_dbgsym_package),true) + # Debug image is simple + install -m644 -D $(builddir)/build-$*/vmlinux \ + $(dbgpkgdir)/usr/lib/debug/boot/vmlinux-$(abi_release)-$* + if [ -d $(builddir)/build-$*/scripts/gdb/linux ]; then \ + install -m644 -D $(builddir)/build-$*/vmlinux-gdb.py \ + $(dbgpkgdir)/usr/share/gdb/auto-load/boot/vmlinux-$(abi_release)-$*/vmlinuz-$(abi_release)-$*-gdb.py; \ + install -m644 -D $(builddir)/build-$*/scripts/gdb/linux/* \ + --target-directory=$(dbgpkgdir)/usr/share/gdb/auto-load/boot/vmlinux-$(abi_release)-$*/scripts/gdb/linux; \ + fi + $(kmake) O=$(builddir)/build-$* modules_install $(vdso) \ + INSTALL_MOD_PATH=$(dbgpkgdir)/usr/lib/debug + # Add .gnu_debuglink sections only after all/DKMS modules are built. + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/build + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/source + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/modules.* + rm -fr $(dbgpkgdir)/usr/lib/debug/lib/firmware +endif +ifeq ($(do_tools_bpftool),true) + cp $(builddir)/build-$*/vmlinux tools/bpf/bpftool/ +endif + + # The flavour specific headers image + # TODO: Would be nice if we didn't have to dupe the original builddir + install -d -m755 $(hdrdir) + cp $(builddir)/build-$*/.config $(hdrdir) + chmod 644 $(hdrdir)/.config + $(kmake) O=$(hdrdir) -j1 syncconfig prepare scripts + # Makefile may need per-arch-flavour CC settings, which are + # normally set via $(kmake) during build + rm -f $(hdrdir)/Makefile + cp -a $(indep_hdrdir)/Makefile $(hdrdir)/Makefile + sed -i 's|\(^HOSTCC = \)gcc$$|\1$(gcc)|' $(hdrdir)/Makefile + sed -i 's|\(^CC = $$(CROSS_COMPILE)\)gcc$$|\1$(gcc)|' $(hdrdir)/Makefile + # Quick check for successful substitutions + grep '^HOSTCC .*$(gcc)$$' $(hdrdir)/Makefile + grep '^CC .*$(gcc)$$' $(hdrdir)/Makefile + rm -rf $(hdrdir)/include2 $(hdrdir)/source + # Copy over the compilation version. + cp "$(builddir)/build-$*/include/generated/compile.h" \ + "$(hdrdir)/include/generated/compile.h" + # Add UTS_UBUNTU_RELEASE_ABI since UTS_RELEASE is difficult to parse. + echo "#define UTS_UBUNTU_RELEASE_ABI $(abinum)" >> $(hdrdir)/include/generated/utsrelease.h + # powerpc kernel arch seems to need some .o files for external module linking. Add them in. +ifeq ($(build_arch),powerpc) + mkdir -p $(hdrdir)/arch/powerpc/lib + cp $(builddir)/build-$*/arch/powerpc/lib/*.o $(hdrdir)/arch/powerpc/lib +endif +ifeq ($(build_arch),s390) + if [ -n "$$(find $(builddir)/build-$*/arch/s390/lib/expoline -maxdepth 1 -name '*.o' -print -quit)" ]; then \ + mkdir -p $(hdrdir)/arch/s390/lib/expoline/; \ + cp $(builddir)/build-$*/arch/s390/lib/expoline/*.o $(hdrdir)/arch/s390/lib/expoline/; \ + fi +endif + # Copy over scripts/module.lds for building external modules + cp $(builddir)/build-$*/scripts/module.lds $(hdrdir)/scripts + # Script to symlink everything up + $(SHELL) $(DROOT)/scripts/link-headers "$(hdrdir)" "$(indeppkg)" "$*" + # The build symlink + install -d debian/$(basepkg)-$*/lib/modules/$(abi_release)-$* + $(LN) /usr/src/$(basepkg)-$* \ + debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*/build + # And finally the symvers + install -m644 $(builddir)/build-$*/Module.symvers \ + $(hdrdir)/Module.symvers + + # Now the header scripts + $(call install_control,$(hdrs_pkg_name)-$*,headers,postinst) + + # At the end of the package prep, call the tests + DPKG_ARCH="$(arch)" KERN_ARCH="$(build_arch)" FLAVOUR="$*" \ + VERSION="$(abi_release)" REVISION="$(revision)" \ + PREV_REVISION="$(prev_revision)" ABI_NUM="$(abinum)" \ + PREV_ABI_NUM="$(prev_abinum)" BUILD_DIR="$(builddir)/build-$*" \ + INSTALL_DIR="$(pkgdir)" SOURCE_DIR="$(CURDIR)" \ + run-parts -v $(DROOT)/tests-build + + # + # Remove files which are generated at installation by postinst, + # except for modules.order and modules.builtin + # + # NOTE: need to keep this list in sync with postrm + # + mkdir $(pkgdir)/lib/modules/$(abi_release)-$*/_ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.order \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_ + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin ] ; then \ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_; \ + fi + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo ] ; then \ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_; \ + fi + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.* + mv $(pkgdir)/lib/modules/$(abi_release)-$*/_/* \ + $(pkgdir)/lib/modules/$(abi_release)-$* + rmdir $(pkgdir)/lib/modules/$(abi_release)-$*/_ + +ifeq ($(do_linux_tools),true) + # Create the linux-tools tool links + install -d $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +ifeq ($(do_tools_usbip),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/usbip $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/usbipd $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_acpidbg),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/acpidbg $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_cpupower),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/cpupower $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_rtla),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/rtla $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_perf),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/perf $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +ifeq ($(do_tools_perf_jvmti),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/libperf-jvmti.so $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +endif +ifeq ($(do_tools_bpftool),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/bpftool $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_x86),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/x86_energy_perf_policy $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/turbostat $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + # Create the linux-hyperv tool links + install -d $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_kvp_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_vss_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_fcopy_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/lsvmbus $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +endif + + # Build a temporary "installed headers" directory. + install -d $(dkms_dir) $(dkms_dir)/headers $(dkms_dir)/build $(dkms_dir)/source + cp -rp "$(hdrdir)" "$(indep_hdrdir)" "$(dkms_dir)/headers" + + $(foreach _m,$(all_dkms_modules), \ + $(if $(enable_$(_m)), \ + $(call build_dkms,$(dkms_$(_m)_pkg_name)-$*,$(dkms_$(_m)_pkgdir)/lib/modules/$(abi_release)-$*/$(dkms_$(_m)_subdir),$(dbgpkgdir_dkms),$(_m),$(dkms_$(_m)_debpath)); \ + ) \ + ) + + +ifeq ($(do_dbgsym_package),true) + # Add .gnu_debuglink sections to each stripped .ko + # pointing to unstripped verson + find $(pkgdir) \ + $(if $(filter true,$(do_extras_package)),$(pkgdir_ex)) \ + -name '*.ko' | while read path_module ; do \ + module="/lib/modules/$${path_module#*/lib/modules/}"; \ + if [[ -f "$(dbgpkgdir)/usr/lib/debug/$$module" ]] ; then \ + while IFS= read -r -d '' signature < <(tail -c 28 "$$path_module"); do \ + break; \ + done; \ + $(CROSS_COMPILE)objcopy \ + --add-gnu-debuglink=$(dbgpkgdir)/usr/lib/debug/$$module \ + $$path_module; \ + if grep -q CONFIG_MODULE_SIG=y $(builddir)/build-$*/.config && \ + [ "$$signature" = $$'~Module signature appended~\n' ]; then \ + $(builddir)/build-$*/scripts/sign-file $(MODHASHALGO) \ + $(MODSECKEY) \ + $(MODPUBKEY) \ + $$path_module; \ + fi; \ + else \ + echo "WARNING: Missing debug symbols for module '$$module'."; \ + fi; \ + done +endif + + # Build the final ABI information. + install -d $(abidir) + sed -e 's/^\(.\+\)[[:space:]]\+\(.\+\)[[:space:]]\(.\+\)$$/\3 \2 \1/' \ + $(builddir)/build-$*/Module.symvers | sort > $(abidir)/$* + + # Build the final ABI modules information. + find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) \( -name '*.ko' -o -name '*.ko.*' \) | \ + sed -e 's/.*\/\([^\/]*\)\.ko.*/\1/' | sort > $(abidir)/$*.modules + + # Build the final ABI built-in modules information. + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin ] ; then \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin | \ + sort > $(abidir)/$*.modules.builtin; \ + fi + + # Build the final ABI firmware information. + find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | \ + while read ko; do \ + /sbin/modinfo $$ko | grep ^firmware || true; \ + done | sort -u >$(abidir)/$*.fwinfo + + # Build the final ABI built-in firmware information. + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo ] ; then \ + cat $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo | \ + tr '\0' '\n' | sed -n 's/^.*firmware=/firmware: /p' | \ + sort -u > $(abidir)/$*.fwinfo.builtin; \ + fi + + # Build the final ABI compiler information. + ko=$$(find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | head -1); \ + readelf -p .comment "$$ko" | gawk ' \ + ($$1 == "[") { \ + printf("%s", $$3); \ + for (n=4; n<=NF; n++) { \ + printf(" %s", $$n); \ + } \ + print "" \ + }' | sort -u >$(abidir)/$*.compiler + + # Build the buildinfo package content. + install -d $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$* + install -m644 $(builddir)/build-$*/.config \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/config + install -m644 $(abidir)/$* \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/abi + install -m644 $(abidir)/$*.modules \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/modules + install -m644 $(abidir)/$*.fwinfo \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/fwinfo + install -m644 $(abidir)/$*.compiler \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/compiler + if [ -f $(abidir)/$*.modules.builtin ] ; then \ + install -m644 $(abidir)/$*.modules.builtin \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/modules.builtin; \ + fi + if [ -f $(abidir)/$*.fwinfo.builtin ] ; then \ + install -m644 $(abidir)/$*.fwinfo.builtin \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/fwinfo.builtin; \ + fi + install -m644 $(DROOT)/canonical-certs.pem $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/canonical-certs.pem + install -m644 $(DROOT)/canonical-revoked-certs.pem $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/canonical-revoked-certs.pem + + # Get rid of .o and .cmd artifacts in headers + find $(hdrdir) -name \*.o -or -name \*.cmd -exec rm -f {} \; + # Strip .so files (e.g., rust/libmacros.so) to reduce size even more + find $(hdrdir) -name libmacros.so -exec strip -s {} \; + +ifeq ($(do_lib_rust),true) + # Generate Rust lib files + install -d -m755 $(rustdir) + mv $(hdrdir)/rust $(rustdir) + # Generate symlink for Rust lib directory in headers + $(SHELL) $(DROOT)/scripts/link-lib-rust "$(hdrdir)" "$(indeppkg)" "$*" +endif + +ifneq ($(do_full_build),false) + # Clean out this flavours build directory. + rm -rf $(builddir)/build-$* +endif + $(stamp) + +headers_tmp := $(CURDIR)/debian/tmp-headers +headers_dir := $(CURDIR)/debian/linux-libc-dev + +.PHONY: install-arch-headers +install-arch-headers: + @echo Debug: $@ + dh_testdir + dh_testroot + $(call if_package, linux-libc-dev, dh_prep -plinux-libc-dev) + rm -rf $(headers_tmp) $(headers_dir) + $(kmake) O=$(headers_tmp) INSTALL_HDR_PATH=$(headers_dir)/usr $(conc_level) headers_install + mkdir $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH) + mv $(headers_dir)/usr/include/asm $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)/ + rm -rf $(headers_tmp) + +define dh_all + dh_installchangelogs -p$(1) + dh_installdocs -p$(1) + dh_compress -p$(1) + # Compress kernel modules, on mantic+ + $(if $(do_zstd_ko),find debian/$(1) -name '*.ko' -print0 | xargs -0 -n1 -P $(CONCURRENCY_LEVEL) -r zstd -19 --quiet --rm, true) + dh_fixperms -p$(1) -X/boot/ + dh_shlibdeps -p$(1) $(shlibdeps_opts) + dh_installdeb -p$(1) + dh_installdebconf -p$(1) + $(lockme) dh_gencontrol -p$(1) -- -Vlinux:rprovides='$(rprovides)' $(2) + dh_md5sums -p$(1) + dh_builddeb -p$(1) +endef +define newline + + +endef +define dh_all_inline + $(subst ${newline},; \${newline},$(call dh_all,$(1),$(2))) +endef + +.PHONY: binary-arch-headers +binary-arch-headers: install-arch-headers + @echo Debug: $@ + dh_testdir + dh_testroot + $(call if_package, linux-libc-dev, $(call dh_all,linux-libc-dev)) + +-include $(builddir)/skipped-dkms.mk +binary-%: pkgimg = $(bin_pkg_name)-$* +binary-%: pkgimg_mods = $(mods_pkg_name)-$* +binary-%: pkgimg_ex = $(mods_extra_pkg_name)-$* +binary-%: pkgdir_ex = $(CURDIR)/debian/$(extra_pkg_name)-$* +binary-%: pkgbldinfo = $(bldinfo_pkg_name)-$* +binary-%: pkghdr = $(hdrs_pkg_name)-$* +binary-%: pkgrust = $(rust_pkg_name)-$* +binary-%: dbgpkg = $(bin_pkg_name)-$*-dbgsym +binary-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym +binary-%: pkgtools = $(tools_flavour_pkg_name)-$* +binary-%: pkgcloud = $(cloud_flavour_pkg_name)-$* +$(foreach _m,$(all_dkms_modules), \ + $(eval binary-%: enable_$(_m) = $$(filter true,$$(call custom_override,do_$(_m),$$*))) \ +) +binary-%: rprovides = $(foreach _m,$(all_built-in_dkms_modules),$(if $(enable_$(_m)),$(foreach _r,$(dkms_$(_m)_rprovides),$(_r)$(comma) ))) +binary-%: target_flavour = $* +binary-%: checks-% + @echo Debug: $@ + dh_testdir + dh_testroot + + $(call dh_all,$(pkgimg)) -- -Znone + $(call dh_all,$(pkgimg_mods))$(if $(do_zstd_ko), -- -Znone) + +ifeq ($(do_extras_package),true) + ifeq ($(ship_extras_package),false) + # If $(ship_extras_package) is explicitly set to false, then do not + # construct the linux-image-extra package; instead just log all of the + # "extra" modules which were pointlessly built yet won't be shipped. + find $(pkgdir_ex) -name '*.ko' | sort \ + | sed 's|^$(pkgdir_ex)/|NOT-SHIPPED |' \ + | tee -a $(target_flavour).not-shipped.log; + else + if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \ + $(call dh_all_inline,$(pkgimg_ex))$(if $(do_zstd_ko), -- -Znone); \ + fi + endif +endif + + $(foreach _m,$(all_standalone_dkms_modules), \ + $(if $(enable_$(_m)),$(call dh_all,$(dkms_$(_m)_pkg_name)-$*)$(if $(do_zstd_ko), -- -Znone);)\ + ) + + $(call dh_all,$(pkgbldinfo)) + $(call dh_all,$(pkghdr)) +ifeq ($(do_lib_rust),true) + $(call dh_all,$(pkgrust)) +endif + +ifeq ($(do_dbgsym_package),true) + $(call dh_all,$(dbgpkg)) -- -Zxz + + # Hokay...here's where we do a little twiddling... + # Renaming the debug package prevents it from getting into + # the primary archive, and therefore prevents this very large + # package from being mirrored. It is instead, through some + # archive admin hackery, copied to http://ddebs.ubuntu.com. + # + mv ../$(dbgpkg)_$(release)-$(revision)_$(arch).deb \ + ../$(dbgpkg)_$(release)-$(revision)_$(arch).ddeb + $(lockme) sed -i '/^$(dbgpkg)_/s/\.deb /.ddeb /' debian/files + # Now, the package wont get into the archive, but it will get put + # into the debug system. + + # Clean out the debugging package source directory. + rm -rf $(dbgpkgdir) +endif + +ifeq ($(do_linux_tools),true) + $(call dh_all,$(pkgtools)) +endif +ifeq ($(do_cloud_tools),true) + $(call dh_all,$(pkgcloud)) +endif + +# +# per-architecture packages +# +builddirpa = $(builddir)/tools-perarch + +$(stampdir)/stamp-prepare-perarch: + @echo Debug: $@ +ifeq ($(do_any_tools),true) + rm -rf $(builddirpa) + install -d $(builddirpa) + rsync -a --exclude debian --exclude debian.master --exclude $(DEBIAN) --exclude .git -a ./ $(builddirpa)/ +endif + $(stamp) + +$(stampdir)/stamp-build-perarch: $(stampdir)/stamp-prepare-perarch install-arch-headers build-arch + @echo Debug: $@ +ifeq ($(do_linux_tools),true) +ifeq ($(do_tools_usbip),true) + chmod 755 $(builddirpa)/tools/usb/usbip/autogen.sh + cd $(builddirpa)/tools/usb/usbip && ./autogen.sh + chmod 755 $(builddirpa)/tools/usb/usbip/configure + cd $(builddirpa)/tools/usb/usbip && ./configure --prefix=$(builddirpa)/tools/usb/usbip/bin + cd $(builddirpa)/tools/usb/usbip && make install CFLAGS="-g -O2 -static" CROSS_COMPILE=$(CROSS_COMPILE) +endif +ifeq ($(do_tools_acpidbg),true) + cd $(builddirpa)/tools/power/acpi && make clean && make CFLAGS="-g -O2 -static -I$(builddirpa)/include" CROSS_COMPILE=$(CROSS_COMPILE) acpidbg +endif +ifeq ($(do_tools_rtla),true) + cd $(builddirpa)/tools/tracing/rtla && make clean && make CFLAGS='-g -O -Wall -I/usr/include/tracefs -I/usr/include/traceevent -DVERSION="\"6.8.1\""' static +endif +ifeq ($(do_tools_cpupower),true) + make -C $(builddirpa)/tools/power/cpupower \ + CROSS_COMPILE=$(CROSS_COMPILE) \ + CROSS=$(CROSS_COMPILE) \ + STATIC=true \ + CPUFREQ_BENCH=false +endif +ifeq ($(do_tools_perf),true) + cd $(builddirpa) && $(kmake) $(defconfig) + mv $(builddirpa)/.config $(builddirpa)/.config.old + sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \ + -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \ + $(builddirpa)/.config.old > $(builddirpa)/.config + cd $(builddirpa) && $(kmake) syncconfig + cd $(builddirpa) && $(kmake) prepare + cd $(builddirpa)/tools/perf && \ + $(kmake) prefix=/usr HAVE_CPLUS_DEMANGLE_SUPPORT=1 CROSS_COMPILE=$(CROSS_COMPILE) NO_LIBPERL=1 WERROR=0 +endif +ifeq ($(do_tools_bpftool),true) + mv $(builddirpa)/tools/bpf/bpftool/vmlinux $(builddirpa)/vmlinux + $(kmake) CROSS_COMPILE=$(CROSS_COMPILE) -C $(builddirpa)/tools/bpf/bpftool + rm -f $(builddirpa)/vmlinux +endif +ifeq ($(do_tools_x86),true) + cd $(builddirpa)/tools/power/x86/x86_energy_perf_policy && make CROSS_COMPILE=$(CROSS_COMPILE) + cd $(builddirpa)/tools/power/x86/turbostat && make CROSS_COMPILE=$(CROSS_COMPILE) +endif +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + cd $(builddirpa)/tools/hv && make CFLAGS="-I$(headers_dir)/usr/include -I$(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)" CROSS_COMPILE=$(CROSS_COMPILE) hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon +endif +endif + $(stamp) + +.PHONY: install-perarch +install-perarch: toolspkgdir = $(CURDIR)/debian/$(tools_pkg_name) +install-perarch: cloudpkgdir = $(CURDIR)/debian/$(cloud_pkg_name) +install-perarch: $(stampdir)/stamp-build-perarch + @echo Debug: $@ + # Add the tools. +ifeq ($(do_linux_tools),true) + install -d $(toolspkgdir)/usr/lib + install -d $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +ifeq ($(do_tools_usbip),true) + install -m755 $(addprefix $(builddirpa)/tools/usb/usbip/bin/sbin/, usbip usbipd) \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_acpidbg),true) + install -m755 $(builddirpa)/tools/power/acpi/acpidbg \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_cpupower),true) + install -m755 $(builddirpa)/tools/power/cpupower/cpupower \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_rtla),true) + install -m755 $(builddirpa)/tools/tracing/rtla/rtla-static \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)/rtla +endif +ifeq ($(do_tools_perf),true) + install -m755 $(builddirpa)/tools/perf/perf $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +ifeq ($(do_tools_perf_jvmti),true) + install -m755 $(builddirpa)/tools/perf/libperf-jvmti.so $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_perf_python),true) + install -d $(toolspkgdir)/usr/lib/python3/dist-packages/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/perf/python/perf*.so $(toolspkgdir)/usr/lib/python3/dist-packages/$(src_pkg_name)-tools-$(abi_release) +endif +endif +ifeq ($(do_tools_bpftool),true) + install -m755 $(builddirpa)/tools/bpf/bpftool/bpftool $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_x86),true) + install -m755 \ + $(addprefix $(builddirpa)/tools/power/x86/, x86_energy_perf_policy/x86_energy_perf_policy turbostat/turbostat) \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + install -d $(cloudpkgdir)/usr/lib + install -d $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(addprefix $(builddirpa)/tools/hv/, hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon lsvmbus) \ + $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +endif + +.PHONY: binary-perarch +binary-perarch: toolspkg = $(tools_pkg_name) +binary-perarch: cloudpkg = $(cloud_pkg_name) +binary-perarch: install-perarch + @echo Debug: $@ +ifeq ($(do_linux_tools),true) + $(call dh_all,$(toolspkg)) +endif +ifeq ($(do_cloud_tools),true) + $(call dh_all,$(cloudpkg)) +endif + +.PHONY: binary-debs +binary-debs: binary-perarch $(addprefix binary-,$(flavours)) + @echo Debug: $@ + +build-arch-deps-$(do_flavour_image_package) += $(addprefix $(stampdir)/stamp-install-,$(flavours)) + +.PHONY: build-arch +build-arch: $(build-arch-deps-true) + @echo Debug: $@ + +binary-arch-deps-$(do_flavour_image_package) += binary-debs +binary-arch-deps-true += binary-arch-headers +ifneq ($(do_common_headers_indep),true) +binary-arch-deps-$(do_flavour_header_package) += binary-headers +endif + +.PHONY: binary-arch +binary-arch: $(binary-arch-deps-true) + @echo Debug: $@ + --- linux-xilinx-6.8.0.orig/debian/rules.d/3-binary-indep.mk +++ linux-xilinx-6.8.0/debian/rules.d/3-binary-indep.mk @@ -0,0 +1,213 @@ +.PHONY: build-indep +build-indep: + @echo Debug: $@ + +# The binary-indep dependency chain is: +# +# install-headers <- install-source <- install-tools <- install-indep <- binary-indep +# install-headers <- binary-headers +# +indep_hdrpkg = $(indep_hdrs_pkg_name) +indep_hdrdir = $(CURDIR)/debian/$(indep_hdrpkg)/usr/src/$(indep_hdrpkg) + +$(stampdir)/stamp-install-headers: $(stampdir)/stamp-prepare-indep + @echo Debug: $@ + dh_testdir + +ifeq ($(do_flavour_header_package),true) + install -d $(indep_hdrdir) + find . -path './debian' -prune -o -path './$(DEBIAN)' -prune \ + -o -path './include/*' -prune \ + -o -path './scripts/*' -prune -o -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) \ + -print | cpio -pd --preserve-modification-time $(indep_hdrdir) + cp -a scripts include $(indep_hdrdir) + (find arch -name include -type d -print | \ + xargs -n1 -i: find : -type f) | \ + cpio -pd --preserve-modification-time $(indep_hdrdir) + # Do not ship .o and .cmd artifacts in headers + find $(indep_hdrdir) -name \*.o -or -name \*.cmd -exec rm -f {} \; +endif + $(stamp) + +srcpkg = linux-source-$(release) +srcdir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg) +balldir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg)/$(srcpkg) +install-source: $(stampdir)/stamp-prepare-indep + @echo Debug: $@ +ifeq ($(do_source_package),true) + + install -d $(srcdir) +ifeq ($(do_source_package_content),true) + find . -path './debian' -prune -o -path './$(DEBIAN)' -prune -o \ + -path './.*' -prune -o -print | \ + cpio -pd --preserve-modification-time $(balldir) + (cd $(srcdir); tar cf - $(srcpkg)) | bzip2 -9c > \ + $(srcdir)/$(srcpkg).tar.bz2 + rm -rf $(balldir) + $(LN) $(srcpkg)/$(srcpkg).tar.bz2 $(srcdir)/.. +endif +endif + +.PHONY: install-tools +install-tools: toolspkg = $(tools_common_pkg_name) +install-tools: toolsbin = $(CURDIR)/debian/$(toolspkg)/usr/bin +install-tools: toolssbin = $(CURDIR)/debian/$(toolspkg)/usr/sbin +install-tools: toolsman = $(CURDIR)/debian/$(toolspkg)/usr/share/man +install-tools: toolspython = $(CURDIR)/debian/$(toolspkg)/usr/lib/python3/dist-packages +install-tools: toolsbashcomp = $(CURDIR)/debian/$(toolspkg)/usr/share/bash-completion/completions +install-tools: hosttoolspkg = $(hosttools_pkg_name) +install-tools: hosttoolsbin = $(CURDIR)/debian/$(hosttoolspkg)/usr/bin +install-tools: hosttoolsman = $(CURDIR)/debian/$(hosttoolspkg)/usr/share/man +install-tools: hosttoolssystemd = $(CURDIR)/debian/$(hosttoolspkg)/lib/systemd/system +install-tools: cloudpkg = $(cloud_common_pkg_name) +install-tools: cloudbin = $(CURDIR)/debian/$(cloudpkg)/usr/bin +install-tools: cloudsbin = $(CURDIR)/debian/$(cloudpkg)/usr/sbin +install-tools: cloudman = $(CURDIR)/debian/$(cloudpkg)/usr/share/man +install-tools: $(stampdir)/stamp-prepare-indep $(stampdir)/stamp-build-perarch + @echo Debug: $@ + +ifeq ($(do_tools_common),true) + rm -rf $(builddir)/tools + install -d $(builddir)/tools + for i in *; do $(LN) $(CURDIR)/$$i $(builddir)/tools/; done + rm $(builddir)/tools/tools + rsync -a tools/ $(builddir)/tools/tools/ + + install -d $(toolsbin) + install -d $(toolssbin) + install -d $(toolsman)/man1 + install -d $(toolsman)/man8 + install -d $(toolsbashcomp) + install -d $(toolspython) + + install -m755 debian/tools/generic $(toolsbin)/usbip + install -m755 debian/tools/generic $(toolsbin)/usbipd + install -m644 $(CURDIR)/tools/usb/usbip/doc/*.8 $(toolsman)/man8/ + + install -m755 debian/tools/generic $(toolsbin)/cpupower + install -m644 $(CURDIR)/tools/power/cpupower/man/*.1 $(toolsman)/man1/ + + install -m755 debian/tools/generic $(toolsbin)/rtla + + install -m755 debian/tools/generic $(toolsbin)/perf + + install -m755 debian/tools/generic $(toolssbin)/bpftool + make -C $(builddir)/tools/tools/bpf/bpftool doc + install -m644 $(builddir)/tools/tools/bpf/bpftool/Documentation/*.8 \ + $(toolsman)/man8 + install -m644 $(builddir)/tools/tools/bpf/bpftool/bash-completion/bpftool \ + $(toolsbashcomp) + + install -m755 debian/tools/generic $(toolsbin)/x86_energy_perf_policy + install -m755 debian/tools/generic $(toolsbin)/turbostat + + cd $(builddir)/tools/tools/perf && make man + install -m644 $(builddir)/tools/tools/perf/Documentation/*.1 \ + $(toolsman)/man1 + + install -m644 $(CURDIR)/tools/power/x86/x86_energy_perf_policy/*.8 $(toolsman)/man8 + install -m644 $(CURDIR)/tools/power/x86/turbostat/*.8 $(toolsman)/man8 + +ifeq ($(do_tools_perf_python),true) + # Python wrapper module for python-perf + install -d $(toolspython)/perf + install -m755 debian/tools/python-perf.py $(toolspython)/perf/__init__.py +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + install -d $(cloudsbin) + install -m755 debian/tools/generic $(cloudsbin)/hv_kvp_daemon + install -m755 debian/tools/generic $(cloudsbin)/hv_vss_daemon + install -m755 debian/tools/generic $(cloudsbin)/hv_fcopy_daemon + install -m755 debian/tools/generic $(cloudsbin)/lsvmbus + install -m755 debian/cloud-tools/hv_get_dhcp_info $(cloudsbin) + install -m755 debian/cloud-tools/hv_get_dns_info $(cloudsbin) + install -m755 debian/cloud-tools/hv_set_ifconfig $(cloudsbin) + + install -d $(cloudman)/man8 + install -m644 $(CURDIR)/tools/hv/*.8 $(cloudman)/man8 +endif +endif + +ifeq ($(do_tools_acpidbg),true) + install -m755 debian/tools/generic $(toolsbin)/acpidbg +endif + +endif + +ifeq ($(do_tools_host),true) + install -d $(hosttoolsbin) + install -d $(hosttoolsman)/man1 + install -d $(hosttoolssystemd) + + install -m 755 $(CURDIR)/tools/kvm/kvm_stat/kvm_stat $(hosttoolsbin)/ + install -m 644 $(CURDIR)/tools/kvm/kvm_stat/kvm_stat.service \ + $(hosttoolssystemd)/ + + cd $(builddir)/tools/tools/kvm/kvm_stat && make man + install -m644 $(builddir)/tools/tools/kvm/kvm_stat/*.1 \ + $(hosttoolsman)/man1 +endif + +$(stampdir)/stamp-prepare-indep: + @echo Debug: $@ + dh_prep -i + $(stamp) + +.PHONY: install-indep +install-indep: $(stampdir)/stamp-install-headers install-source install-tools + @echo Debug: $@ + +# This is just to make it easy to call manually. Normally done in +# binary-indep target during builds. +.PHONY: binary-headers +binary-headers: $(stampdir)/stamp-prepare-indep $(stampdir)/stamp-install-headers + @echo Debug: $@ + dh_installchangelogs -p$(indep_hdrpkg) + dh_installdocs -p$(indep_hdrpkg) + dh_compress -p$(indep_hdrpkg) + dh_fixperms -p$(indep_hdrpkg) + dh_installdeb -p$(indep_hdrpkg) + $(lockme) dh_gencontrol -p$(indep_hdrpkg) + dh_md5sums -p$(indep_hdrpkg) + dh_builddeb -p$(indep_hdrpkg) + +binary-indep: cloudpkg = $(cloud_common_pkg_name) +binary-indep: hosttoolspkg = $(hosttools_pkg_name) +binary-indep: install-indep + @echo Debug: $@ + dh_installchangelogs -i + dh_installdocs -i + dh_compress -i + dh_fixperms -i +ifeq ($(do_tools_common),true) +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + dh_installinit -p$(cloudpkg) -n --name hv-kvp-daemon + dh_installinit -p$(cloudpkg) -n --name hv-vss-daemon + dh_installinit -p$(cloudpkg) -n --name hv-fcopy-daemon + dh_installudev -p$(cloudpkg) -n --name hv-kvp-daemon + dh_installudev -p$(cloudpkg) -n --name hv-vss-daemon + dh_installudev -p$(cloudpkg) -n --name hv-fcopy-daemon + dh_systemd_enable -p$(cloudpkg) + dh_installinit -p$(cloudpkg) -o --name hv-kvp-daemon + dh_installinit -p$(cloudpkg) -o --name hv-vss-daemon + dh_installinit -p$(cloudpkg) -o --name hv-fcopy-daemon + dh_systemd_start -p$(cloudpkg) +endif + # Keep intel_sgx service disabled by default, so add it after dh_systemd_enable + # and dh_systemd_start are called: + dh_installinit -p$(cloudpkg) --no-start --no-enable --name intel-sgx-load-module +endif +endif +ifeq ($(do_tools_host),true) + # Keep kvm_stat.service disabled by default (after dh_systemd_enable + # and dh_systemd_start: + dh_installinit -p$(hosttoolspkg) --no-enable --no-start --name kvm_stat +endif + dh_installdeb -i + $(lockme) dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i --- linux-xilinx-6.8.0.orig/debian/rules.d/4-checks.mk +++ linux-xilinx-6.8.0/debian/rules.d/4-checks.mk @@ -0,0 +1,18 @@ +# Check the signature of staging modules +module-signature-check-%: $(stampdir)/stamp-install-% + @echo Debug: $@ + $(DROOT)/scripts/checks/module-signature-check "$*" \ + "$(DROOT)/$(mods_pkg_name)-$*" \ + "$(DROOT)/$(mods_extra_pkg_name)-$*" \ + $(do_skip_checks) + +checks-%: module-signature-check-% + @echo Debug: $@ + +# Check the config against the known options list. +config-prepare-check-%: $(stampdir)/stamp-prepare-tree-% + @echo Debug: $@ +ifneq ($(do_skip_checks),true) + python3 $(DROOT)/scripts/misc/annotations -f $(commonconfdir)/annotations \ + --arch $(arch) --flavour $* --check $(builddir)/build-$*/.config +endif --- linux-xilinx-6.8.0.orig/debian/scripts/checks/final-checks +++ linux-xilinx-6.8.0/debian/scripts/checks/final-checks @@ -0,0 +1,47 @@ +#!/bin/bash + +debian="$1" +abi="$2" + +archs=$(awk '/^Architecture:/ { $1=""; for (i=1; i<=NF; i++) { if ($i != "all") { print $i }}}' debian/control | sort -u) + +fail=0 + +failure() +{ + echo "EE: $*" 1>&2 + fail=1 +} + +for arch in $archs +do + if [ ! -f "$debian/rules.d/$arch.mk" ]; then + continue + fi + + image_pkg=$(awk -F '\\s*=\\s*' '$1 == "do_flavour_image_package" { print $2 }' "$debian/rules.d/$arch.mk") + if [ "$image_pkg" = "false" ]; then + continue + fi + + flavours=$( + awk '/^\s*flavours\s*=/{ + sub(/^\s*flavours\s*=\s*/, ""); + print + }' "$debian/rules.d/$arch.mk") + for flavour in $flavours + do + if [ -d debian/certs ]; then + if ! python3 debian/scripts/misc/annotations --export -c CONFIG_SYSTEM_TRUSTED_KEYS --arch "$arch" --flavour "$flavour" | grep -q '^CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"$' ; then + failure "'CONFIG_SYSTEM_TRUSTED_KEYS=\"debian/canonical-certs.pem\"' is required" + fi + fi + if [ -d debian/revoked-certs ]; then + if ! python3 debian/scripts/misc/annotations --export -c CONFIG_SYSTEM_REVOCATION_KEYS --arch "$arch" --flavour "$flavour" | grep -q '^CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"$' ; then + failure "'CONFIG_SYSTEM_REVOCATION_KEYS=\"debian/canonical-revoked-certs.pem\"' is required" + fi + fi + done +done + +exit "$fail" --- linux-xilinx-6.8.0.orig/debian/scripts/checks/module-signature-check +++ linux-xilinx-6.8.0/debian/scripts/checks/module-signature-check @@ -0,0 +1,91 @@ +#!/bin/bash -eu + +flavor="${1}" +mods_dir="${2}" +mods_extra_dir="${3}" + +skip_checks=${4:-} +case "${skip_checks,,}" in + 1|true|yes) skip_checks=1 ;; + *) skip_checks=0 ;; +esac + +echo "II: Checking signature of staging modules for ${flavor}..." + +root=$(dirname "$(realpath -e "${0}")")/../../.. +. "${root}"/debian/debian.env + +# Collect the signature-inclusion files +sig_incs=() +for d in debian "${DEBIAN}" ; do + if [ -f "${root}"/"${d}"/signature-inclusion ] ; then + sig_incs+=("${root}"/"${d}"/signature-inclusion) + fi +done + +if [ "${#sig_incs[@]}" -gt 0 ] ; then + echo "II: Use signature inclusion file(s):" + printf " %s\n" "${sig_incs[@]}" + sig_all=0 +else + echo "WW: Signature inclusion file(s) missing" + echo "II: All modules must be signed" + sig_all=1 +fi + +if ! [ -d "${mods_dir}" ] ; then + echo "EE: Modules directory missing:" + echo " ${mods_dir}" + if [ ${skip_checks} -eq 1 ] ; then + echo "WW: Explicitly asked to ignore failures" + echo "II: Done" + exit 0 + fi + exit 1 +fi + +echo "II: Checking modules directory:" +echo " ${mods_dir}" +mods_dirs=("${mods_dir}") + +if [ -d "${mods_extra_dir}" ] ; then + echo " ${mods_extra_dir}" + mods_dirs+=("${mods_extra_dir}") +fi + +pass=0 +fail=0 +while IFS= read -r mod ; do + is=0 + if /sbin/modinfo "${mod}" | grep -q "^signature:" ; then + # Module is signed + is=1 + fi + + must=0 + if [ ${sig_all} -eq 1 ] || grep -qFx "${mod##*/}" "${sig_incs[@]}" ; then + # Module must be signed + must=1 + fi + + case "${is}${must}" in + 00) echo " PASS (unsigned) : ${mod##*/}" ; pass=$((pass + 1)) ;; + 01) echo " FAIL (unsigned) : ${mod##*/}" ; fail=$((fail + 1)) ;; + 10) echo " FAIL (signed) : ${mod##*/}" ; fail=$((fail + 1)) ;; + 11) echo " PASS (signed) : ${mod##*/}" ; pass=$((pass + 1)) ;; + esac +done < <(find "${mods_dirs[@]}" -path '*/drivers/staging/*.ko' | sort) + +echo "II: Checked $((pass + fail)) modules : ${pass} PASS, ${fail} FAIL" + +if [ ${fail} -ne 0 ] ; then + if [ ${skip_checks} -eq 1 ] ; then + echo "WW: Explicitly asked to ignore failures" + else + echo "EE: Modules signature failures" + exit 1 + fi +fi + +echo "II: Done" +exit 0 --- linux-xilinx-6.8.0.orig/debian/scripts/control-create +++ linux-xilinx-6.8.0/debian/scripts/control-create @@ -0,0 +1,62 @@ +#!/bin/bash + +. debian/debian.env + +vars=$1 +any_signed=$2 + +. $vars + +[ "$provides" != '' ] && provides="$provides, " + +flavour=$(basename $vars | sed 's/.*\.//') +stub="${DEBIAN}/control.d/flavour-control.stub debian/control.d/flavour-buildinfo.stub" +if [ "$any_signed" = 'true' ]; then + sign_me_pkg="-unsigned" + sign_me_txt=" unsigned" + sign_peer_pkg="" +else + sign_me_pkg="" + sign_me_txt="" + sign_peer_pkg="-unsigned" +fi + +cat $stub | grep -v '^#' | sed \ + -e "s#FLAVOUR#$flavour#g" \ + -e "s#DESC#$desc#g" \ + -e "s#ARCH#$arch#g" \ + -e "s#SUPPORTED#$supported#g" \ + -e "s#TARGET#$target#g" \ + -e "s#BOOTLOADER#$bootloader#g" \ + -e "s#=PROVIDES=#$provides#g" \ + -e "s#=CONFLICTS=#$conflicts#g" \ + -e "s#=SIGN-ME-PKG=#$sign_me_pkg#g" \ + -e "s#=SIGN-ME-TXT=#$sign_me_txt#g" \ + -e "s#=SIGN-PEER-PKG=#$sign_peer_pkg#g" + +while read package version extras +do + module="$package" + module_type= + + # Module arch parameters are skipped here, so a package section will + # be generated for each flavour, and its Architecture will be set to + # all architectures with that flavour. Even that is being generated, + # it doesn't follow all of them will be built. That's to work-around + # dkms_exclude/dkms_include that manipulates supported architectures + # in $(DEBIAN)/rules.d/$(arch).mk. + for param in $extras; do + case "$param" in + modulename=*) module="${param#modulename=}" ;; + type=*) module_type="${param#type=}" ;; + *) continue ;; + esac + done + + [ "$module_type" = "standalone" ] || continue + + cat debian/control.d/flavour-module.stub | grep -v '^#' | sed \ + -e "s#ARCH#$arch#g" \ + -e "s#MODULE#$module#g" \ + -e "s#FLAVOUR#$flavour#g" +done <"${DEBIAN}/dkms-versions" --- linux-xilinx-6.8.0.orig/debian/scripts/dkms-build +++ linux-xilinx-6.8.0/debian/scripts/dkms-build @@ -0,0 +1,271 @@ +#!/bin/sh +set -e + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +here=$(dirname "$(readlink -f "${0}")") + +srcdir=$(pwd) +cd "$dkms_dir" || exit 1 + +built_using_record() +{ + local subst="$1" + local built_using="$2" + if [ ! -f "$subst" ]; then + touch "$subst" + fi + if ! grep -q -s "^linux:BuiltUsing=" "$subst"; then + echo "linux:BuiltUsing=" >>"$subst" + fi + sed -i -e "s/^\(linux:BuiltUsing=.*\)/\1$built_using, /" "$subst" +} + +# ABI: returns present in $? and located path in lpackage_path when found. +package_present() +{ + for lpackage_path in "$1"_*.deb + do + break + done + [ -f "$lpackage_path" ] +} + +# Download and extract the DKMS package -- note there may be more +# than one package to install. +for package_path in "$@" +do + package_file=$(basename "$package_path") + echo "II: dkms-build downloading $package ($package_file)" + rpackage=$( echo "$package_path" | sed -e 's@.*/@@' -e 's@_.*@@' ) + lpackage=$( echo "$rpackage" | sed -e 's@=.*@@' ) + + while true + do + if package_present "$lpackage"; then + break + fi + case "$package_path" in + pool/*) + # Attempt download from the launchpad librarian first. + "$here/file-downloader" "https://launchpad.net/ubuntu/+archive/primary/+files/$package_file" || true + if package_present "$lpackage"; then + break + fi + + # Download from the available pools. + for pool in $( grep -h '^deb ' /etc/apt/sources.list /etc/apt/sources.list.d/*.list | awk '{print $2}' | sort -u ) + do + if package_present "$lpackage"; then + break + fi + url="$pool/$package_path" + "$here/file-downloader" "$url" && break || true + # No components in PPAs. + url=$(echo "$url" | sed -e 's@/pool/[^/]*/@/pool/main/@') + "$here/file-downloader" "$url" && break || true + done + ;; + http*:*) + "$here/file-downloader" "$package_path" + ;; + */*) + cp -p "$package_path" . + ;; + *) + apt-get download "$rpackage" + ;; + esac + break + done + if ! package_present "$lpackage"; then + echo "EE: $lpackage not found" + exit 1 + fi + + dpkg -x "$lpackage"_*.deb "$package" + + lversion=$( echo "$lpackage_path" | sed -e 's@.*/@@' -e 's@_[^_]*$@@' -e 's@.*_@@') + #built_using_record "$srcdir/debian/$pkgname.substvars" "$built_using$lpackage (= $lversion)" +done + +# Pick out the package/version from the dkms.conf. +for dkms_conf in "$package/usr/src"/*/"dkms.conf" +do + break +done + +# It seems some packages have a # in the name which works fine if the +# package is installed directly, but not so much if we build it out +# of the normal location. +sed -i -e '/^PACKAGE_NAME=/ s/#//g' "$dkms_conf" + +# Run any dkms-package specfic configuration steps +dkms_config_specific="$srcdir/$0-configure--$package" +dkms_config_generic=$(echo "$dkms_config_specific" | sed -e 's/-[0-9][0-9]*$/-N/') +for dkms_config in "$dkms_config_specific" "$dkms_config_generic" +do + if [ -z "$dkms_config" -o ! -e "$dkms_config" ]; then + continue + fi + echo "II: dkms-build-configure $(basename "$dkms_config") found, executing" + "$dkms_config" \ + "$srcdir" \ + "$dkms_conf" \ + "$dkms_dir" \ + "$abi_flavour" \ + "$sign" \ + "$pkgname" \ + "$pkgdir" \ + "$dbgpkgdir" \ + "$package" \ + "$@" || exit 1 + break +done + +cat - <<'EOF' >>"$dkms_conf" +POST_BUILD="ubuntu-save-objects ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/objects $POST_BUILD" +EOF +ubuntu_script="$(dirname "$dkms_conf")/ubuntu-save-objects" +cat - <<'EOF' >"$ubuntu_script" +#!/bin/sh +from="$1" +to="$2" +script="$3" +shift 2 + +# Copy the objects. +echo "II: copying objects to '$to'" +mkdir -p "$to" +(cd "$from" && find -name \*.o -o -name \*.mod | cpio -Lpd "$to") + +# Call the original post_install script if there is one. +[ "$script" = '' ] && exit 0 + +shift +exec "$(dirname "$0")/$script" "$@" +EOF +chmod +x "$ubuntu_script" +dkms_package=$( sed -ne 's/PACKAGE_NAME="\(.*\)"/\1/p' "$dkms_conf" ) +dkms_version=$( sed -ne 's/PACKAGE_VERSION="\(.*\)"/\1/p' "$dkms_conf" ) + +# Build the DKMS binaries. +echo "II: dkms-build building $package" +fakeroot="" +[ $(id -u) -ne 0 ] && fakeroot="/usr/bin/fakeroot" +rc=0 +$fakeroot /usr/sbin/dkms build --no-prepare-kernel --no-clean-kernel \ + -k "$abi_flavour" ${ARCH:+-a $ARCH} \ + --sourcetree "$dkms_dir/source" \ + --dkmstree "$dkms_dir/build" \ + --kernelsourcedir "$dkms_dir/headers/linux-headers-$abi_flavour" \ + "$dkms_conf" || rc=$? + +# Find the log and add it to our own. +for log in "$dkms_dir/build/$dkms_package/$dkms_version/$abi_flavour"/*/"log/make.log" "$dkms_dir/build/$dkms_package/$dkms_version/build/make.log" +do + if [ -f "$log" ]; then + sed -e "s@$dkms_dir@<>@g" <"$log" + break + fi +done + +# If this build failed then exit here. +[ "$rc" != 0 ] && exit "$rc" + +# Install the modules with debug symbols we possibly built, +# and strip the original modules for the next install step. +if [ -n "$dbgpkgdir" ]; then + dbgpkgdir="$dbgpkgdir/$package" + echo "II: dkms-build installing $package into $dbgpkgdir (debug symbols)" + install -d "$dbgpkgdir" + find "$dkms_dir/build/$dkms_package/$dkms_version/$abi_version" -name \*.ko | + while read module; do + vmodule=$( basename "$module" ) + + # Check for '.debug_info' section in order to copy module. + # Useful if debug symbols are requested but not built for + # any reason (including not yet supported by DKMS package). + # Strip module just in case even if section isn't present. + if ${CROSS_COMPILE}objdump -h -j '.debug_info' "$module" >/dev/null 2>&1 + then + echo "copying $vmodule" + cp "$module" "$dbgpkgdir" + else + echo "ignoring $vmodule (missing debug symbols)" + fi + + # Just 'strip -g' as '/usr/sbin/dkms' does. + echo "stripping $vmodule" + strip -g "$module" + done +fi + +# Install and optionally sign the modules we have built. +pkgdir="$pkgdir/$package" +echo "II: dkms-build installing $package into $pkgdir" +install -d "$pkgdir" +find "$dkms_dir/build/$dkms_package/$dkms_version/$abi_version" -name \*.ko | +while read module; do + vmodule=$( basename "$module" ) + case "$sign" in + --*) + echo "copying $vmodule" + cp "$module" "$pkgdir" + ;; + *) + echo "signing $vmodule" + $sign "$module" "$pkgdir/$vmodule" + ;; + esac +done + +find "$dkms_dir/build/$dkms_package/$dkms_version/objects" -name \*.o -print | \ +while read object +do + "$srcdir/debian/scripts/fix-filenames" "$object" "$dkms_dir" +done + +# This assumes that .mod files are in the top level build tree +# If there are ever .mod files in sub-directories, the dirname of objectlist needs to be stripped as well +find "$dkms_dir/build/$dkms_package/$dkms_version/objects" -name \*.mod -print | \ +while read objectlist +do + sed "s|^$dkms_dir/build/$dkms_package/$dkms_version/build/||" -i $objectlist +done + +# Finally see if there is a dkms-package specific post processor present. Hand +# it the original source directory, destination package directory, the objects +# as squirreled away, and the log in case it is useful. Finally pass a formed +# signing command line in case we need to do that. +dkms_build_specific="$srcdir/$0--$package" +dkms_build_generic=$(echo "$dkms_build_specific" | sed -n -e 's/-[0-9][0-9]*[a-z]*$/-N/p') +for dkms_build in "$dkms_build_specific" "$dkms_build_generic" +do + if [ -z "$dkms_build" -o ! -e "$dkms_build" ]; then + continue + fi + echo "II: dkms-build override $(basename "$dkms_build") found, executing" + "$dkms_build" \ + "$srcdir" \ + "$dkms_dir/build/$dkms_package/$dkms_version/objects" \ + "$log" \ + "$dkms_dir" \ + "$abi_flavour" \ + "$sign" \ + "$pkgname" \ + "$pkgdir" \ + "$dbgpkgdir" \ + "$package" \ + "$@" || exit 1 + break +done + +echo "II: dkms-build build $package complete" --- linux-xilinx-6.8.0.orig/debian/scripts/dkms-build--nvidia-N +++ linux-xilinx-6.8.0/debian/scripts/dkms-build--nvidia-N @@ -0,0 +1,112 @@ +#!/bin/sh +set -e + +srcdir="$1" +objects="$2" +log="$3" +shift 3 + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +build="$( dirname "$objects" )/build" + +# Copy over the objects ready for reconstruction. The objects copy +# contains the *.o files. For our purposes we only want the *.o files, +# elide the rest. And .mod files for ld linking in recentish kernels. +mkdir -p "$pkgdir/bits/scripts" +( + gcc_variant1=$(gcc --version | head -1 | sed -e 's/^gcc/GCC:/') + gcc_variant2=$(gcc --version | head -1 | sed -e 's/^\(gcc\) \((.*)\) \(.*\)$/\1 version \3 \2/') + cd "$objects" || exit 1 + find -name \*.o -o -name \*.mod | \ + while read file + do + cp --parents "$file" "$pkgdir/bits" + "$srcdir/debian/scripts/fix-filenames" "$pkgdir/bits/$file" "$gcc_variant1" + "$srcdir/debian/scripts/fix-filenames" "$pkgdir/bits/$file" "$gcc_variant2" + done +) + +# Install the support files we need. +echo "II: copying support files ..." +for lds_src in \ + "$dkms_dir/headers/linux-headers-$abi_flavour/scripts/module.lds" \ + "/usr/src/linux-headers-$abi_flavour/scripts/module.lds" \ + "$dkms_dir/headers/linux-headers-$abi_flavour/scripts/module-common.lds" \ + "/usr/src/linux-headers-$abi_flavour/scripts/module-common.lds" +do + [ ! -f "$lds_src" ] && continue + echo "II: copying support files ... found $lds_src" + cp "$lds_src" "$pkgdir/bits/scripts" + break +done + +# Build helper scripts. +cat - <<'EOL' >"$pkgdir/bits/BUILD" +[ "$1" = "unsigned" ] && { signed_only=:; shift; } +[ "$1" = "nocheck" ] && { check_only=:; shift; } +EOL +grep /usr/bin/ld.bfd "$log" | grep -v scripts/genksyms/genksyms | grep -v "warning:\|NOTE:" | sed -e "s@$build/@@g" >>"$pkgdir/bits/BUILD" +sed -e 's/.*-o *\([^ ]*\) .*/rm -f \1/g' <"$pkgdir/bits/BUILD" >"$pkgdir/bits/CLEAN" + +# As the builds contain the absolute filenames as used. Use RECONSTRUCT to +# rebuild the .ko's, sign them, pull off the signatures and then finally clean +# up again. +( + cd "$pkgdir/bits" + + # Add checksum check. + echo "\$check_only sha256sum -c SHA256SUMS || exit 1" >>"$pkgdir/bits/BUILD" + + # Add .ko handling to the CLEAN/BUILD dance. + for ko in "$pkgdir"/*.ko + do + ko=$(basename "$ko") + echo "\$signed_only cat '$ko' '$ko.sig' >'../$ko'" >>"$pkgdir/bits/BUILD" + echo "\$signed_only rm -f '$ko'" >>"$pkgdir/bits/BUILD" + echo "rm -f '../$ko'" >>"$pkgdir/bits/CLEAN" + done + + # Clear out anything we are not going to distribute and build unsigned .kos. + sh ./CLEAN + sh ./BUILD unsigned nocheck + + if [ "$sign" = "--custom" ]; then + # We are building for and archive custom signing upload. Keep everything. + : + elif [ "$sign" = "--lrm" ]; then + # We are in the LRM build; grab sha256 checksums and clean up. + sha256sum -b *.ko >"SHA256SUMS" + sh ./CLEAN + + else + # We are in the main kernel, put the .kos together as we will + # on the users machine, sign them, and keep just the signature. + : >"SHA256SUMS" + for ko in *.ko + do + echo "detached-signature $ko" + $sign "$ko" "$ko.signed" + length=$( stat --format %s "$ko" ) + dd if="$ko.signed" of="$ko.sig" bs=1 skip="$length" 2>/dev/null + + rm -f "$ko.signed" + # Keep a checksum of the pre-signed object so we can check it is + # built correctly in LRM. + sha256sum -b "$ko" >>"SHA256SUMS" + done + + # Clean out anything which not a signature. + mv "$pkgdir/bits/"*.sig "$pkgdir" + mv "$pkgdir/bits/SHA256SUMS" "$pkgdir" + find "$pkgdir" -name \*.sig -prune -o -name SHA256SUMS -prune -o -type f -print | xargs rm -f + find "$pkgdir" -depth -type d -print | xargs rmdir --ignore-fail-on-non-empty + fi +) --- linux-xilinx-6.8.0.orig/debian/scripts/dkms-build-configure--zfs +++ linux-xilinx-6.8.0/debian/scripts/dkms-build-configure--zfs @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +srcdir="$1" +dkms_conf="$2" +shift 2 + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +# ZFS debug symbols are enabled in dkms.conf via PACKAGE_CONFIG file. +if [ -n "$dbgpkgdir" ]; then + echo "enable zfs debug symbols" + pkg_cfg="$(dirname "$dkms_conf")/pkg_cfg" + echo 'ZFS_DKMS_ENABLE_DEBUGINFO=yes' >"$pkg_cfg" + echo 'ZFS_DKMS_DISABLE_STRIP=yes' >>"$pkg_cfg" + sed -i "s,^\(PACKAGE_CONFIG=\).*,\1$pkg_cfg," $dkms_conf +fi --- linux-xilinx-6.8.0.orig/debian/scripts/file-downloader +++ linux-xilinx-6.8.0/debian/scripts/file-downloader @@ -0,0 +1,34 @@ +#!/bin/sh + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi +url="$1" + +to=$(basename "$url") + +count=0 +what='fetching' +while : +do + if [ "$count" -eq 20 ]; then + echo "EE: excessive redirects" 1>&2 + exit 1 + fi + count=$(($count+1)) + + echo "II: $what $url" + + curl --silent --fail --show-error "$url" -o "$to" -D "$to.hdr" || exit 1 + redirect=$(awk '/^Location: / {gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2); print $2;}' "$to.hdr") + [ -z "$redirect" ] && break + what=' following' + + url=$(echo "$redirect" | sed -e 's@https://launchpadlibrarian.net/@http://launchpadlibrarian.net/@') + if [ "$redirect" != "$url" ]; then + echo "II: fixing $redirect" + fi +done + +exit 0 --- linux-xilinx-6.8.0.orig/debian/scripts/fix-filenames.c +++ linux-xilinx-6.8.0/debian/scripts/fix-filenames.c @@ -0,0 +1,80 @@ +/* + * fix-filenames: find a specified pathname prefix and remove it from + * C strings. + * + * Copyright (C) 2018 Canonical Ltd. + * Author: Andy Whitcroft + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int rc; + char *in_name; + char *prefix; + int prefix_len; + int in_fd; + struct stat in_info; + char *in; + off_t size; + int length; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + in_name = argv[1]; + prefix = argv[2]; + prefix_len = strlen(prefix); + + in_fd = open(in_name, O_RDWR); + if (in_fd < 0) { + perror("open input failed"); + exit(1); + } + + rc = fstat(in_fd, &in_info); + if (rc < 0) { + perror("fstat input failed"); + exit(1); + } + size = in_info.st_size; + + in = mmap((void *)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, in_fd, (off_t)0); + if (!in) { + perror("mmap failed"); + exit(1); + } + + for (; size > 0; size--, in++) { + if (*in != *prefix) + continue; + if (strncmp(in, prefix, prefix_len) != 0) + continue; + /* In the case of an exact match there there is nothing to move. */ + if (in[prefix_len] == '\0') + length = 0; + /* If this is a filename, strip the leading slash. */ + else if (in[prefix_len] == '/') + length = strlen(in + prefix_len + 1) + 1; + /* Otherwise just keep the suffix. */ + else + length = strlen(in + prefix_len) + 1; + + /* + * Copy the suffix portion down to the start and clear + * the remainder of the space to 0. + */ + memmove(in, in + prefix_len + 1, length); + memset(in + length, '\0', prefix_len); + } +} --- linux-xilinx-6.8.0.orig/debian/scripts/link-headers +++ linux-xilinx-6.8.0/debian/scripts/link-headers @@ -0,0 +1,42 @@ +#!/bin/bash -e + +. debian/debian.env + +hdrdir="$1" +symdir="$2" +flavour="$3" + +echo "Symlinking and copying headers for $flavour..." + +excludes="( -path ./debian -prune -o -path ./${DEBIAN} -prune -o -path ./.git ) -prune -o" + +( +find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print +find ./include ./scripts -name .gitignore -prune -o -type f -print +find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print +) | ( +while read file; do + dir=$file + lastdir=$file + + if [ -e "$hdrdir/$file" -o -L "$hdrdir/$file" ]; then + continue + fi + + while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do + lastdir=$dir + dir=`dirname $dir` + done + # If the last item to exist is a symlink we assume all is good + if [ ! -L "$hdrdir/$dir" ]; then + # Turns things like "./foo" into "../" + deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`" + item="`echo -n $lastdir | sed -e 's/^\.\///'`" + ln -s $deref$symdir/$item $hdrdir/$item + fi +done +) + +exit --- linux-xilinx-6.8.0.orig/debian/scripts/link-lib-rust +++ linux-xilinx-6.8.0/debian/scripts/link-lib-rust @@ -0,0 +1,17 @@ +#!/bin/bash -e + +. debian/debian.env + +hdrdir="$1" +symdir="$2" +flavour="$3" + +echo "Symlinking and copying Rust files for $flavour..." + +# Symlink Rust folder +item=rust +relpath=$(echo $symdir | sed s/headers/lib-rust/)-$flavour/$item +echo ln -s ../$relpath $hdrdir/$item +ln -s ../$relpath $hdrdir/$item + +exit --- linux-xilinx-6.8.0.orig/debian/scripts/misc/annotations +++ linux-xilinx-6.8.0/debian/scripts/misc/annotations @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# -*- mode: python -*- + +# This file is not installed; it's just to run annotations from inside a source +# distribution without installing it in the system. + +import sys + +# Prevent generating .pyc files on import +# +# We may end up adding these files to our git repos by mistake, so simply +# prevent generating them in advance. +# +# There's a tiny performance penalty with this, because python needs to +# re-generate the bytecode on-the-fly every time the script is executed, but +# this overhead is absolutely negligible compared the rest of the kernel build +# time. +sys.dont_write_bytecode = True + +import os # noqa: E402 Import not at top of file +from kconfig import run # noqa: E402 Import not at top of file + + +# Update PATH to make sure that annotations can be executed directly from the +# source directory. +def update_path(): + script_dir = os.path.dirname(os.path.abspath(__file__)) + current_path = os.environ.get("PATH", "") + new_path = f"{script_dir}:{current_path}" + os.environ["PATH"] = new_path + + +update_path() +exit(run.main()) --- linux-xilinx-6.8.0.orig/debian/scripts/misc/find-missing-sauce.sh +++ linux-xilinx-6.8.0/debian/scripts/misc/find-missing-sauce.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# +# Find the 'UBUNTU: SAUCE:' patches that have been dropped from +# the previous release. +# +PREV_REL=focal +PREV_REPO=git://kernel.ubuntu.com/ubuntu/ubuntu-${PREV_REL}.git + +git fetch ${PREV_REPO} master-next +git log --pretty=oneline FETCH_HEAD|grep SAUCE|while read c m;do echo $m;done |sort > $$.prev-rel +git log --pretty=oneline |grep SAUCE|while read c m;do echo $m;done |sort > $$.curr-rel + +diff -u $$.prev-rel $$.curr-rel |grep "^-" +rm -f $$.prev-rel $$.curr-rel + --- linux-xilinx-6.8.0.orig/debian/scripts/misc/gen-auto-reconstruct +++ linux-xilinx-6.8.0/debian/scripts/misc/gen-auto-reconstruct @@ -0,0 +1,89 @@ +#!/bin/bash + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 | " 1>&2 + exit 1 +fi +tag="$1" +reconstruct="$2" +options="$3" + +case "$tag" in +v*) ;; +*) tag="v${tag%.*}" ;; +esac + +# Validate the tag. +count=$( git tag -l "$tag" | wc -l ) +if [ "$count" != 1 ]; then + echo "$0: $tag: tag invalid" 1>&2 + exit 1 +fi + +#git ls-tree -r --full-tree HEAD | grep ^120 | \ +#while read mode type blobid name + +( + # Identify all new symlinks since the proffered tag. + echo "# Recreate any symlinks created since the orig." + git diff "$tag.." --raw --no-renames | awk '(/^:000000 120000/ && $5 == "A") { print $NF }' | \ + while read name + do + link=$( readlink "$name" ) + + echo "[ ! -L '$name' ] && ln -sf '$link' '$name'" + done + + # Identify files with execute permissions added since the proffered tag. + git diff "$tag.." --raw --no-renames | awk -F '[: \t]' '{print $2, $3, $NF }' | \ + while IFS=" " read old new name + do + old=$( printf "0%s" $old ) + new=$( printf "0%s" $new ) + changed=$(( (old ^ new) & 0111 )) + if [ "$changed" -ne 0 ]; then + added=$(( new & 0111 )) + if [ "$added" -ne 0 ]; then + echo "chmod +x '$name'" + elif [ "$new" -ne 0 ]; then + echo "chmod -x '$name'" + fi + fi + done + + # Identify all removed files since the proffered tag. + echo "# Remove any files deleted from the orig." + git diff "$tag.." --raw --no-renames | awk '(/^:/ && $5 == "D") { print $NF }' | \ + while read name + do + echo "rm -f '$name'" + done + + # All done, make sure this does not complete in error. + echo "exit 0" +) >"$reconstruct" + +( + # Identify all new symlinks since the proffered tag. + echo "# Ignore any symlinks created since the orig which are rebuilt by reconstruct." + git diff "$tag.." --raw --no-renames | awk '(/^:000000 120000/ && $5 == "A") { print $NF }' | \ + while read name + do + echo "extend-diff-ignore=^$name\$" + done +) >"$options.update" + + +head='^## autoreconstruct -- begin$' +foot='^## autoreconstruct -- end$' +sed -i -e " + /$head/,/$foot/{ + /$head/{ + p; + r $options.update + }; + /$foot/p; + d + } +" "$options" +rm -f "$options.update" --- linux-xilinx-6.8.0.orig/debian/scripts/misc/git-ubuntu-log +++ linux-xilinx-6.8.0/debian/scripts/misc/git-ubuntu-log @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 + +import sys + +import codecs +import urllib.request +import json + +import textwrap + +sys.stdin = codecs.getreader("utf-8")(sys.stdin.detach()) +sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach()) + +entries = [] + + +def add_entry(entry): + global tracking_bug + + if entry and 'ignore' not in entry: + combo = [] + for bug in set(entry.get('bugs', [])): + combo.append(bug) + for cve in set(entry.get('cves', [])): + combo.append(cve) + combo = sorted(combo) + + if len(combo) == 0: + if entry.get('subject', "").startswith('UBUNTU'): + combo = '__packaging__' + else: + combo = '__mainline__' + else: + if entry.get('subject', "") == 'UBUNTU: link-to-tracker: update tracking bug': + tracking_bug = combo + if combo not in keys: + keys.append(combo) + + entry['key'] = combo + entries.append(entry) + + +# Suck up the git log output and extract the information we need. +keys = [] +tracking_bug = None +entry = None +subject_wait = False +for line in sys.stdin: + if line.startswith('commit '): + add_entry(entry) + entry = {} + subject_wait = True + + elif line.startswith('Author: '): + bits = line.strip().split(maxsplit=1) + entry['author'] = bits[1] + + elif subject_wait and line.startswith(' '): + subject_wait = False + entry['subject'] = line.strip() + + elif line.startswith(' BugLink: '): + bits = line.strip().split(maxsplit=2) + if len(bits) > 2: + # There is text after the URL, so use that (after stripping the + # enclosing characters) + entry.setdefault('bugs', []).append(bits[2][1:-1]) + elif 'launchpad.net' in bits[1]: + # Extract the bug number from the launchpad URL + bits = bits[1].split('/') + entry.setdefault('bugs', []).append(bits[-1]) + + elif line.startswith(' CVE-'): + entry.setdefault('cves', []).append(line.strip()) + + elif line.startswith(' Ignore:'): + entry['ignore'] = True + + elif line.startswith(' Properties:'): + for prop in line.strip().split()[1:]: + if prop in ('ignore', 'no-changelog'): + entry['ignore'] = True + +add_entry(entry) + +entries.reverse() + +# Go through the entries and clear out authors for upstream commits. +for entry in entries: + if entry['subject'].startswith('UBUNTU:'): + entry['subject'] = entry['subject'][7:].strip() + else: + del entry['author'] + +# Lump everything without a bug at the bottom. +keys.append('__packaging__') +keys.append('__mainline__') + +# Ensure we list the tracking bug updates first. +if tracking_bug is not None: + keys.remove(tracking_bug) + keys.insert(0, tracking_bug) + +emit_nl = False +for key in keys: + if key == '__packaging__': + title_set = ['Miscellaneous Ubuntu changes'] + elif key == '__mainline__': + title_set = ['Miscellaneous upstream changes'] + else: + title_set = [] + for bug in key: + if bug.startswith('CVE-'): + title_set.append(bug) + elif bug.isdigit(): + # Assume that it is an LP bug number if 'bug' contains only digits + bug_info = None + + try: + # urllib.request.urlcleanup() + request = urllib.request.Request('https://api.launchpad.net/devel/bugs/' + bug) + request.add_header('Cache-Control', 'no-cache') + with urllib.request.urlopen(request) as response: + data = response.read() + bug_info = json.loads(data.decode('utf-8')) + + title = bug_info['title'] + if 'description' in bug_info: + for line in bug_info['description'].split('\n'): + if line.startswith('Kernel-Description:'): + title = line.split(' ', 1)[1] + + except urllib.error.HTTPError: + title = 'INVALID or PRIVATE BUG' + + title += ' (LP###' + bug + ')' + title_set.append(title) + else: + # Finally treat 'bug' itself as the title + title_set.append(bug) + + emit_title = True + for entry in entries: + if entry['key'] != key: + continue + + if emit_title: + if emit_nl: + print('') + emit_nl = True + + title_lines = textwrap.wrap('#// '.join(title_set), 76) + print(' * ' + title_lines[0].replace('LP###', 'LP: #').replace('#//', ' //')) + for line in title_lines[1:]: + line = line.replace('LP###', 'LP: #').replace('#//', ' //') + print(' ' + line) + + emit_title = False + + if key != tracking_bug or (key == tracking_bug and entry['subject'] != "link-to-tracker: update tracking bug"): + title_lines = textwrap.wrap(entry['subject'], 76) + print(' - ' + title_lines[0]) + for line in title_lines[1:]: + line = line.replace('LP###', 'LP: #') + print(' ' + line) --- linux-xilinx-6.8.0.orig/debian/scripts/misc/insert-changes +++ linux-xilinx-6.8.0/debian/scripts/misc/insert-changes @@ -0,0 +1,42 @@ +#!/usr/bin/python3 + +import os +import sys + +from subprocess import check_output + +droot = 'debian' +if len(sys.argv) > 1: + droot = sys.argv[1] + +debian = 'debian.master' +if len(sys.argv) > 2: + debian = sys.argv[2] + +rules = os.path.join(droot, 'rules') +changelog = os.path.join(debian, 'changelog') +changelog_new = os.path.join(debian, 'changelog.new') + +# Generate the list of new changes +changes = check_output(['make', '-s', '-f', rules, 'printchanges']).decode('UTF-8') + +# Insert the new changes into the changelog +with open(changelog) as orig, open(changelog_new, 'w') as new: + printed = False + skip_newline = False + for line in orig: + if line.startswith(' CHANGELOG: '): + if not printed: + printed = True + if changes == '': + skip_newline = True + continue + new.write(changes) + else: + if skip_newline and line.strip() == '': + skip_newline = False + continue + new.write(line) + +# Replace the original changelog with the new one +os.rename(changelog_new, changelog) --- linux-xilinx-6.8.0.orig/debian/scripts/misc/insert-ubuntu-changes +++ linux-xilinx-6.8.0/debian/scripts/misc/insert-ubuntu-changes @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +import re +import os +import sys + +def version_cmp(a, b): + a = re.split(r"[\.-]+", a) + b = re.split(r"[\.-]+", b) + i = 0 + while True: + if len(a) <= i: + if len(b) <= i: + return 0 + return -1 + if len(b) <= i: + return 1 + if int(a[i]) < int(b[i]): + return -1 + if int(a[i]) > int(b[i]): + return 1 + i += 1 + +if len(sys.argv) == 4: + sys.argv.append("debian.master/changelog") + +if len(sys.argv) == 5: + changelog, end, start, source_changelog = sys.argv[1:] +else: + print("Usage: insert-ubuntu-changes []") + sys.exit(1) + +changes = [] +output = False +with open(source_changelog) as fh: + for line in fh: + m = re.match(r"^\S+\s+\((.*)\)", line) + if m: + if version_cmp(m.group(1), end) <= 0: + break + if m.group(1) == start: + output = True + if output: + changes.append("\n") + changes.append(" [ Ubuntu: {} ]\n".format(m.group(1))) + changes.append("\n") + continue + + if output and re.match(r"^( * | | )\S", line): + changes.append(line) + +printed = 3 +with open(changelog + ".new", "w") as fh_new: + with open(changelog) as fh: + for line in fh: + if line.startswith(" CHANGELOG: "): + printed -= 1 + fh_new.write(line) + if printed == 0: + fh_new.write("".join(changes)) + continue + fh_new.write(line) + +os.rename(changelog + ".new", changelog) --- linux-xilinx-6.8.0.orig/debian/scripts/misc/kconfig/annotations.py +++ linux-xilinx-6.8.0/debian/scripts/misc/kconfig/annotations.py @@ -0,0 +1,522 @@ +# -*- mode: python -*- +# python module to manage Ubuntu kernel .config and annotations +# Copyright © 2022 Canonical Ltd. + +import json +import re +import shutil +import tempfile + +from abc import abstractmethod +from ast import literal_eval +from os.path import dirname, abspath + +from kconfig.version import ANNOTATIONS_FORMAT_VERSION + + +class Config: + def __init__(self, fname, do_include=True): + """ + Basic configuration file object + """ + self.fname = fname + self.config = {} + self.do_include = do_include + + raw_data = self._load(fname) + self._parse(raw_data) + + @staticmethod + def _load(fname: str) -> str: + with open(fname, "rt", encoding="utf-8") as fd: + data = fd.read() + return data.rstrip() + + def __str__(self): + """Return a JSON representation of the config""" + return json.dumps(self.config, indent=4) + + @abstractmethod + def _parse(self, data: str): + pass + + +class KConfig(Config): + """ + Parse a .config file, individual config options can be accessed via + .config[] + """ + + def _parse(self, data: str): + self.config = {} + for line in data.splitlines(): + m = re.match(r"^# (CONFIG_.*) is not set$", line) + if m: + self.config[m.group(1)] = literal_eval("'n'") + continue + m = re.match(r"^(CONFIG_[A-Za-z0-9_]+)=(.*)$", line) + if m: + self.config[m.group(1)] = literal_eval("'" + m.group(2) + "'") + continue + + +class Annotation(Config): + """ + Parse body of annotations file + """ + + def __init__(self, fname, do_include=True, do_json=False): + self.do_json = do_json + super().__init__(fname, do_include=True) + + def _parse_body(self, data: str, parent=True): + for line in data.splitlines(): + # Replace tabs with spaces, squeeze multiple into singles and + # remove leading and trailing spaces + line = line.replace("\t", " ") + line = re.sub(r" +", " ", line) + line = line.strip() + + # Ignore empty lines + if not line: + continue + + # Catpure flavors of included files + if line.startswith("# FLAVOUR: "): + self.include_flavour += line.split(" ")[2:] + continue + + # Ignore comments + if line.startswith("#"): + continue + + # Handle includes (recursively) + m = re.match(r'^include\s+"?([^"]*)"?', line) + if m: + if parent: + self.include.append(m.group(1)) + if self.do_include: + include_fname = dirname(abspath(self.fname)) + "/" + m.group(1) + include_data = self._load(include_fname) + self._parse_body(include_data, parent=False) + continue + + # Handle policy and note lines + if re.match(r".* (policy|note)<", line): + try: + conf = line.split(" ")[0] + if conf in self.config: + entry = self.config[conf] + else: + entry = {"policy": {}} + + match = False + m = re.match(r".* policy<(.*?)>", line) + if m: + match = True + # Update the previous entry considering potential overrides: + # - if the new entry is adding a rule for a new + # arch/flavour, simply add that + # - if the new entry is overriding a previous + # arch-flavour item, then overwrite that item + # - if the new entry is overriding a whole arch, then + # remove all the previous flavour rules of that arch + new_entry = literal_eval(m.group(1)) + for key in new_entry: + if key in self.arch: + for flavour_key in list(entry["policy"].keys()): + if flavour_key.startswith(key): + del entry["policy"][flavour_key] + entry["policy"][key] = new_entry[key] + else: + entry["policy"][key] = new_entry[key] + + m = re.match(r".* note<(.*?)>", line) + if m: + entry["oneline"] = match + match = True + entry["note"] = "'" + m.group(1).replace("'", "") + "'" + + if not match: + raise SyntaxError("syntax error") + self.config[conf] = entry + except Exception as e: + raise SyntaxError(str(e) + f", line = {line}") from e + continue + + # Invalid line + raise SyntaxError(f"invalid line: {line}") + + def _legacy_parse(self, data: str): + """ + Parse main annotations file, individual config options can be accessed + via self.config[] + """ + self.config = {} + self.arch = [] + self.flavour = [] + self.flavour_dep = {} + self.include = [] + self.header = "" + self.include_flavour = [] + + # Parse header (only main header will considered, headers in includes + # will be treated as comments) + for line in data.splitlines(): + if re.match(r"^#.*", line): + m = re.match(r"^# ARCH: (.*)", line) + if m: + self.arch = list(m.group(1).split(" ")) + m = re.match(r"^# FLAVOUR: (.*)", line) + if m: + self.flavour = list(m.group(1).split(" ")) + m = re.match(r"^# FLAVOUR_DEP: (.*)", line) + if m: + self.flavour_dep = literal_eval(m.group(1)) + self.header += line + "\n" + else: + break + + # Return an error if architectures are not defined + if not self.arch: + raise SyntaxError("ARCH not defined in annotations") + # Return an error if flavours are not defined + if not self.flavour: + raise SyntaxError("FLAVOUR not defined in annotations") + + # Parse body + self._parse_body(data) + + # Sanity check: Verify that all FLAVOUR_DEP flavors are valid + if self.do_include: + for src, tgt in self.flavour_dep.items(): + if src not in self.flavour: + raise SyntaxError(f"Invalid source flavour in FLAVOUR_DEP: {src}") + if tgt not in self.include_flavour: + raise SyntaxError(f"Invalid target flavour in FLAVOUR_DEP: {tgt}") + + def _json_parse(self, data, is_included=False): + data = json.loads(data) + + # Check if version is supported + version = data["attributes"]["_version"] + if version > ANNOTATIONS_FORMAT_VERSION: + raise SyntaxError(f"annotations format version {version} not supported") + + # Check for top-level annotations vs imported annotations + if not is_included: + self.config = data["config"] + self.arch = data["attributes"]["arch"] + self.flavour = data["attributes"]["flavour"] + self.flavour_dep = data["attributes"]["flavour_dep"] + self.include = data["attributes"]["include"] + self.include_flavour = [] + else: + # We are procesing an imported annotations, so merge all the + # configs and attributes. + try: + self.config = data["config"] | self.config + except TypeError: + self.config = {**self.config, **data["config"]} + self.arch = list(set(self.arch) | set(data["attributes"]["arch"])) + self.flavour = list(set(self.flavour) | set(data["attributes"]["flavour"])) + self.include_flavour = list(set(self.include_flavour) | set(data["attributes"]["flavour"])) + self.flavour_dep = self.flavour_dep | data["attributes"]["flavour_dep"] + + # Handle recursive inclusions + if self.do_include: + for f in data["attributes"]["include"]: + include_fname = dirname(abspath(self.fname)) + "/" + f + data = self._load(include_fname) + self._json_parse(data, is_included=True) + + def _parse(self, data: str): + if self.do_json: + self._json_parse(data, is_included=False) + else: + self._legacy_parse(data) + + def _remove_entry(self, config: str): + if self.config[config]: + del self.config[config] + + def remove(self, config: str, arch: str = None, flavour: str = None): + if config not in self.config: + return + if arch is not None: + if flavour is not None: + flavour = f"{arch}-{flavour}" + else: + flavour = arch + del self.config[config]["policy"][flavour] + if not self.config[config]["policy"]: + self._remove_entry(config) + else: + self._remove_entry(config) + + def set( + self, + config: str, + arch: str = None, + flavour: str = None, + value: str = None, + note: str = None, + ): + if value is not None: + if config not in self.config: + self.config[config] = {"policy": {}} + if arch is not None: + if flavour is not None: + flavour = f"{arch}-{flavour}" + else: + flavour = arch + self.config[config]["policy"][flavour] = value + else: + for a in self.arch: + self.config[config]["policy"][a] = value + if note is not None: + self.config[config]["note"] = "'" + note.replace("'", "") + "'" + + def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = None): + """Merge configs from a Kconfig object into Annotation object""" + + # Determine if we need to import all configs or a single config + if not configs: + configs = c.config.keys() + try: + configs |= self.search_config(arch=arch, flavour=flavour).keys() + except TypeError: + configs = { + **configs, + **self.search_config(arch=arch, flavour=flavour).keys(), + } + + # Import configs from the Kconfig object into Annotations + flavour_arg = flavour + if flavour is not None: + flavour = arch + f"-{flavour}" + else: + flavour = arch + for conf in configs: + if conf in c.config: + val = c.config[conf] + else: + val = "-" + if conf in self.config: + if "policy" in self.config[conf]: + # Add a TODO if a config with a note is changing and print + # a warning + old_val = self.search_config(config=conf, arch=arch, flavour=flavour_arg) + if old_val: + old_val = old_val[conf] + if val != old_val and "note" in self.config[conf]: + self.config[conf]["note"] = "TODO: update note" + print(f"WARNING: {conf} changed from {old_val} to {val}, updating note") + self.config[conf]["policy"][flavour] = val + else: + self.config[conf]["policy"] = {flavour: val} + else: + self.config[conf] = {"policy": {flavour: val}} + + def _compact(self): + # Try to remove redundant settings: if the config value of a flavour is + # the same as the one of the main arch simply drop it. + for conf in self.config.copy(): + if "policy" not in self.config[conf]: + continue + for flavour in self.flavour: + if flavour not in self.config[conf]["policy"]: + continue + m = re.match(r"^(.*?)-(.*)$", flavour) + if not m: + continue + arch = m.group(1) + if arch in self.config[conf]["policy"]: + if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][arch]: + del self.config[conf]["policy"][flavour] + continue + if flavour not in self.flavour_dep: + continue + generic = self.flavour_dep[flavour] + if generic in self.config[conf]["policy"]: + if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][generic]: + del self.config[conf]["policy"][flavour] + continue + # Remove rules for flavours / arches that are not supported (not + # listed in the annotations header). + for flavour in self.config[conf]["policy"].copy(): + if flavour not in list(set(self.arch + self.flavour)): + del self.config[conf]["policy"][flavour] + # Remove configs that are all undefined across all arches/flavours + # (unless we have includes) + if not self.include: + if "policy" in self.config[conf]: + if list(set(self.config[conf]["policy"].values())) == ["-"]: + self.config[conf]["policy"] = {} + # Drop empty rules + if not self.config[conf]["policy"]: + del self.config[conf] + else: + # Compact same value across all flavour within the same arch + for arch in self.arch: + arch_flavours = [i for i in self.flavour if i.startswith(arch)] + value = None + for flavour in arch_flavours: + if flavour not in self.config[conf]["policy"]: + break + if value is None: + value = self.config[conf]["policy"][flavour] + elif value != self.config[conf]["policy"][flavour]: + break + else: + for flavour in arch_flavours: + del self.config[conf]["policy"][flavour] + self.config[conf]["policy"][arch] = value + # After the first round of compaction we may end up having configs that + # are undefined across all arches, so do another round of compaction to + # drop these settings that are not needed anymore + # (unless we have includes). + if not self.include: + for conf in self.config.copy(): + # Remove configs that are all undefined across all arches/flavours + if "policy" in self.config[conf]: + if list(set(self.config[conf]["policy"].values())) == ["-"]: + self.config[conf]["policy"] = {} + # Drop empty rules + if not self.config[conf]["policy"]: + del self.config[conf] + + @staticmethod + def _sorted(config): + """Sort configs alphabetically but return configs with a note first""" + w_note = [] + wo_note = [] + for c in sorted(config): + if "note" in config[c]: + w_note.append(c) + else: + wo_note.append(c) + return w_note + wo_note + + def save(self, fname: str): + """Save annotations data to the annotation file""" + # Compact annotations structure + self._compact() + + # Save annotations to disk + with tempfile.NamedTemporaryFile(mode="w+t", delete=False) as tmp: + # Write header + tmp.write(self.header + "\n") + + # Write includes + for i in self.include: + tmp.write(f'include "{i}"\n') + if self.include: + tmp.write("\n") + + # Write config annotations and notes + tmp.flush() + shutil.copy(tmp.name, fname) + tmp_a = Annotation(fname) + + # Only save local differences (preserve includes) + marker = False + for conf in self._sorted(self.config): + new_val = self.config[conf] + if "policy" not in new_val: + continue + + # If new_val is a subset of old_val, skip it unless there are + # new notes that are different than the old ones. + old_val = tmp_a.config.get(conf) + if old_val and "policy" in old_val: + try: + can_skip = old_val["policy"] == old_val["policy"] | new_val["policy"] + except TypeError: + can_skip = old_val["policy"] == { + **old_val["policy"], + **new_val["policy"], + } + if can_skip: + if "note" not in new_val: + continue + if "note" in old_val and "note" in new_val: + if old_val["note"] == new_val["note"]: + continue + + # Write out the policy (and note) line(s) + val = dict(sorted(new_val["policy"].items())) + line = f"{conf : <47} policy<{val}>" + if "note" in new_val: + val = new_val["note"] + if new_val.get("oneline", False): + # Single line + line += f" note<{val}>" + else: + # Separate policy and note lines, + # followed by an empty line + line += f"\n{conf : <47} note<{val}>\n" + elif not marker: + # Write out a marker indicating the start of annotations + # without notes + tmp.write("\n# ---- Annotations without notes ----\n\n") + marker = True + tmp.write(line + "\n") + + # Replace annotations with the updated version + tmp.flush() + shutil.move(tmp.name, fname) + + def search_config(self, config: str = None, arch: str = None, flavour: str = None) -> dict: + """Return config value of a specific config option or architecture""" + if flavour is None: + flavour = "generic" + flavour = f"{arch}-{flavour}" + if flavour in self.flavour_dep: + generic = self.flavour_dep[flavour] + else: + generic = flavour + if config is None and arch is None: + # Get all config options for all architectures + return self.config + if config is None and arch is not None: + # Get config options of a specific architecture + ret = {} + for c, val in self.config.items(): + if "policy" not in val: + continue + if flavour in val["policy"]: + ret[c] = val["policy"][flavour] + elif generic != flavour and generic in val["policy"]: + ret[c] = val["policy"][generic] + elif arch in val["policy"]: + ret[c] = val["policy"][arch] + return ret + if config is not None and arch is None: + # Get a specific config option for all architectures + return self.config[config] if config in self.config else None + if config is not None and arch is not None: + # Get a specific config option for a specific architecture + if config in self.config: + if "policy" in self.config[config]: + if flavour in self.config[config]["policy"]: + return {config: self.config[config]["policy"][flavour]} + if generic != flavour and generic in self.config[config]["policy"]: + return {config: self.config[config]["policy"][generic]} + if arch in self.config[config]["policy"]: + return {config: self.config[config]["policy"][arch]} + return None + + @staticmethod + def to_config(data: dict) -> str: + """Convert annotations data to .config format""" + s = "" + for c in data: + v = data[c] + if v == "n": + s += f"# {c} is not set\n" + elif v == "-": + pass + else: + s += f"{c}={v}\n" + return s.rstrip() --- linux-xilinx-6.8.0.orig/debian/scripts/misc/kconfig/run.py +++ linux-xilinx-6.8.0/debian/scripts/misc/kconfig/run.py @@ -0,0 +1,370 @@ +# -*- mode: python -*- +# Manage Ubuntu kernel .config and annotations +# Copyright © 2022 Canonical Ltd. + +import sys +import os +import argparse +import json +from signal import signal, SIGPIPE, SIG_DFL + +try: + from argcomplete import autocomplete +except ModuleNotFoundError: + # Allow to run this program also when argcomplete is not available + def autocomplete(_unused): + pass + + +from kconfig.annotations import Annotation, KConfig # noqa: E402 Import not at top of file +from kconfig.utils import autodetect_annotations, arg_fail # noqa: E402 Import not at top of file +from kconfig.version import VERSION, ANNOTATIONS_FORMAT_VERSION # noqa: E402 Import not at top of file + + +SKIP_CONFIGS = ( + # CONFIG_VERSION_SIGNATURE is dynamically set during the build + "CONFIG_VERSION_SIGNATURE", + # Allow to use a different versions of toolchain tools + "CONFIG_GCC_VERSION", + "CONFIG_CC_VERSION_TEXT", + "CONFIG_AS_VERSION", + "CONFIG_LD_VERSION", + "CONFIG_LLD_VERSION", + "CONFIG_CLANG_VERSION", + "CONFIG_PAHOLE_VERSION", + "CONFIG_RUSTC_VERSION_TEXT", + "CONFIG_BINDGEN_VERSION_TEXT", +) + + +def make_parser(): + parser = argparse.ArgumentParser( + description="Manage Ubuntu kernel .config and annotations", + ) + parser.add_argument("--version", "-v", action="version", version=f"%(prog)s {VERSION}") + + parser.add_argument( + "--file", + "-f", + action="store", + help="Pass annotations or .config file to be parsed", + ) + parser.add_argument("--arch", "-a", action="store", help="Select architecture") + parser.add_argument("--flavour", "-l", action="store", help='Select flavour (default is "generic")') + parser.add_argument("--config", "-c", action="store", help="Select a specific config option") + parser.add_argument("--query", "-q", action="store_true", help="Query annotations") + parser.add_argument( + "--note", + "-n", + action="store", + help="Write a specific note to a config option in annotations", + ) + parser.add_argument( + "--autocomplete", + action="store_true", + help="Enable config bash autocomplete: `source <(annotations --autocomplete)`", + ) + parser.add_argument( + "--source", + "-t", + action="store_true", + help="Jump to a config definition in the kernel source code", + ) + parser.add_argument( + "--no-include", + action="store_true", + help="Do not process included annotations (stop at the main file)", + ) + parser.add_argument( + "--json", + action="store_true", + help="Try to parse annotations file in pure JSON format", + ) + + ga = parser.add_argument_group(title="Action").add_mutually_exclusive_group(required=False) + ga.add_argument( + "--write", + "-w", + action="store", + metavar="VALUE", + dest="value", + help="Set a specific config value in annotations (use 'null' to remove)", + ) + ga.add_argument( + "--export", + "-e", + action="store_true", + help="Convert annotations to .config format", + ) + ga.add_argument( + "--import", + "-i", + action="store", + metavar="FILE", + dest="import_file", + help="Import a full .config for a specific arch and flavour into annotations", + ) + ga.add_argument( + "--update", + "-u", + action="store", + metavar="FILE", + dest="update_file", + help="Import a partial .config into annotations (only resync configs specified in FILE)", + ) + ga.add_argument( + "--check", + "-k", + action="store", + metavar="FILE", + dest="check_file", + help="Validate kernel .config with annotations", + ) + return parser + + +_ARGPARSER = make_parser() + + +def export_result(data): + # Dump metadata / attributes first + out = '{\n "attributes": {\n' + for key, value in sorted(data["attributes"].items()): + out += f' "{key}": {json.dumps(value)},\n' + out = out.rstrip(",\n") + out += "\n }," + print(out) + + configs_with_note = {key: value for key, value in data["config"].items() if "note" in value} + configs_without_note = {key: value for key, value in data["config"].items() if "note" not in value} + + # Dump configs, sorted alphabetically, showing items with a note first + out = ' "config": {\n' + for key in sorted(configs_with_note) + sorted(configs_without_note): + policy = data["config"][key]["policy"] + if "note" in data["config"][key]: + note = data["config"][key]["note"] + out += f' "{key}": {{"policy": {json.dumps(policy)}, "note": {json.dumps(note)}}},\n' + else: + out += f' "{key}": {{"policy": {json.dumps(policy)}}},\n' + out = out.rstrip(",\n") + out += "\n }\n}" + print(out) + + +def print_result(config, data): + if data is not None and config is not None and config not in data: + data = {config: data} + print(json.dumps(data, sort_keys=True, indent=2)) + + +def do_query(args): + if args.arch is None and args.flavour is not None: + arg_fail(_ARGPARSER, "error: --flavour requires --arch") + a = Annotation(args.file, do_include=(not args.no_include), do_json=args.json) + res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) + # If no arguments are specified dump the whole annotations structure + if args.config is None and args.arch is None and args.flavour is None: + res = { + "attributes": { + "arch": a.arch, + "flavour": a.flavour, + "flavour_dep": a.flavour_dep, + "include": a.include, + "_version": ANNOTATIONS_FORMAT_VERSION, + }, + "config": res, + } + export_result(res) + else: + print_result(args.config, res) + + +def do_autocomplete(args): + a = Annotation(args.file) + res = (c.removeprefix("CONFIG_") for c in a.search_config()) + res_str = " ".join(res) + print(f'complete -W "{res_str}" annotations') + + +def do_source(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --source requires --config") + if not os.path.exists("tags"): + print("tags not found in the current directory, try: `make tags`") + sys.exit(1) + os.system(f"vim -t {args.config}") + + +def do_note(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --note requires --config") + + # Set the note in annotations + a = Annotation(args.file) + a.set(args.config, note=args.note) + + # Save back to annotations + a.save(args.file) + + # Query and print back the value + a = Annotation(args.file) + res = a.search_config(config=args.config) + print_result(args.config, res) + + +def do_write(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --write requires --config") + + # Set the value in annotations ('null' means remove) + a = Annotation(args.file) + if args.value == "null": + a.remove(args.config, arch=args.arch, flavour=args.flavour) + else: + a.set( + args.config, + arch=args.arch, + flavour=args.flavour, + value=args.value, + note=args.note, + ) + + # Save back to annotations + a.save(args.file) + + # Query and print back the value + a = Annotation(args.file) + res = a.search_config(config=args.config) + print_result(args.config, res) + + +def do_export(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --export requires --arch") + a = Annotation(args.file) + conf = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) + if conf: + print(a.to_config(conf)) + + +def do_import(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --import") + if args.flavour is None: + arg_fail(_ARGPARSER, "error: --flavour is required with --import") + if args.config is not None: + arg_fail(_ARGPARSER, "error: --config cannot be used with --import (try --update)") + + # Merge with the current annotations + a = Annotation(args.file) + c = KConfig(args.import_file) + a.update(c, arch=args.arch, flavour=args.flavour) + + # Save back to annotations + a.save(args.file) + + +def do_update(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --update") + + # Merge with the current annotations + a = Annotation(args.file) + c = KConfig(args.update_file) + if args.config is None: + configs = list(set(c.config.keys()) - set(SKIP_CONFIGS)) + if configs: + a.update(c, arch=args.arch, flavour=args.flavour, configs=configs) + + # Save back to annotations + a.save(args.file) + + +def do_check(args): + # Determine arch and flavour + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --check") + + print(f"check-config: loading annotations from {args.file}") + total = good = ret = 0 + + # Load annotations settings + a = Annotation(args.file) + a_configs = a.search_config(arch=args.arch, flavour=args.flavour).keys() + + # Parse target .config + c = KConfig(args.check_file) + c_configs = c.config.keys() + + # Validate .config against annotations + for conf in sorted(a_configs | c_configs): + if conf in SKIP_CONFIGS: + continue + entry = a.search_config(config=conf, arch=args.arch, flavour=args.flavour) + expected = entry[conf] if entry else "-" + value = c.config[conf] if conf in c.config else "-" + if value != expected: + policy = a.config[conf] if conf in a.config else "undefined" + if "policy" in policy: + policy = f"policy<{policy['policy']}>" + print(f"check-config: {conf} changed from {expected} to {value}: {policy})") + ret = 1 + else: + good += 1 + total += 1 + + num = total - good + if ret: + if os.path.exists(".git"): + print(f"check-config: {num} config options have been changed, review them with `git diff`") + else: + print(f"check-config: {num} config options have changed") + else: + print("check-config: all good") + sys.exit(ret) + + +def main(): + # Prevent broken pipe errors when showing output in pipe to other tools + # (less for example) + signal(SIGPIPE, SIG_DFL) + + # Main annotations program + autocomplete(_ARGPARSER) + args = _ARGPARSER.parse_args() + + if args.file is None: + args.file = autodetect_annotations() + if args.file is None: + arg_fail( + _ARGPARSER, + "error: could not determine DEBDIR, try using: --file/-f", + show_usage=False, + ) + + if args.config and not args.config.startswith("CONFIG_"): + args.config = "CONFIG_" + args.config + + if args.value: + do_write(args) + elif args.note: + do_note(args) + elif args.export: + do_export(args) + elif args.import_file: + do_import(args) + elif args.update_file: + do_update(args) + elif args.check_file: + do_check(args) + elif args.autocomplete: + do_autocomplete(args) + elif args.source: + do_source(args) + else: + do_query(args) + + +if __name__ == "__main__": + main() --- linux-xilinx-6.8.0.orig/debian/scripts/misc/kconfig/utils.py +++ linux-xilinx-6.8.0/debian/scripts/misc/kconfig/utils.py @@ -0,0 +1,20 @@ +# -*- mode: python -*- +# Misc helpers for Kconfig and annotations +# Copyright © 2023 Canonical Ltd. + +import sys + + +def autodetect_annotations(): + try: + with open("debian/debian.env", "rt", encoding="utf-8") as fd: + return fd.read().rstrip().split("=")[1] + "/config/annotations" + except (FileNotFoundError, IndexError): + return None + + +def arg_fail(parser, message, show_usage=True): + print(message) + if show_usage: + parser.print_usage() + sys.exit(1) --- linux-xilinx-6.8.0.orig/debian/scripts/misc/kconfig/version.py +++ linux-xilinx-6.8.0/debian/scripts/misc/kconfig/version.py @@ -0,0 +1,10 @@ +# -*- mode: python -*- +# version of annotations module +# Copyright © 2022 Canonical Ltd. + +VERSION = "0.1" + +ANNOTATIONS_FORMAT_VERSION = 5 + +if __name__ == "__main__": + print(VERSION) --- linux-xilinx-6.8.0.orig/debian/scripts/misc/kernelconfig +++ linux-xilinx-6.8.0/debian/scripts/misc/kernelconfig @@ -0,0 +1,178 @@ +#!/bin/bash -u +# +# Manage kernel config annotations +# +# Supported environment variales: +# conc_level : Concurrency level for upstream make (-jX) +# skip_checks : Skip config checks if set to 'true' +# gcc : Default gcc to use (mandatory) +# + +function cleanup() +{ + rm -rf build "${TMP_DIR}" +} + +# We have to be in the top level Ubuntu kernel source directory +if ! [ -e debian/debian.env ] ; then + echo "ERROR: This is not an Ubuntu kernel source directory" >&2 + exit 1 +fi + +if [ -z "${gcc:-}" ] ; then + echo "ERROR: 'gcc' environment variable must be set" >&2 + exit 1 +fi + +if [ ${#} -ne 1 ] ; then + echo "Usage: $0 updateconfigs|defaultconfigs|genconfigs|editconfigs" + exit 2 +fi + +mode=${1} + +case "${mode}" in + updateconfigs) target="syncconfig" ;; + defaultconfigs) target="olddefconfig" ;; + genconfigs) target="oldconfig" ;; + editconfigs) ;; # Target is set later based on user input + *) echo "ERROR: Invalid mode: ${1}" >&2 + exit 1 ;; +esac + +. debian/debian.env + +annotations_file=${DEBIAN}/config/annotations +warning_partial=() + +TMP_DIR=$(mktemp -d) +trap cleanup EXIT + +# Use annotations to generate configs +FLAVOURS=$(sed -ne 's/^# FLAVOUR: //p' "${annotations_file}") + +for arch_flavour in ${FLAVOURS} ; do + arch=${arch_flavour%%-*} + flavour=${arch_flavour#*-} + tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour} + + # Map debian archs to kernel archs + case "${arch}" in + amd64) kern_arch="x86_64" ;; + arm64) kern_arch="arm64" ;; + armhf) kern_arch="arm" ;; + ppc64el) kern_arch="powerpc" ;; + riscv64) kern_arch="riscv" ;; + s390x) kern_arch="s390" ;; + *) echo "WARNING: Unsupported architecture: ${arch}" + warning_partial+=("${arch}") + continue ;; + esac + + # Determine cross toolchain to use for Kconfig compiler tests + cross_compile="$(dpkg-architecture -qDEB_HOST_GNU_TYPE -a"${arch}" 2>/dev/null)-" + + # Arch-specific compiler, if any + arch_gcc=$(cat < build/.config + + # Environment variables for 'make *config' + env=(ARCH="${kern_arch}" + DEB_ARCH="${arch}" + CROSS_COMPILE="${cross_compile}" + CC="${gcc_path}") + + # Concurrency level + if [ -n "${conc_level:-}" ] ; then + env+=("${conc_level}") + fi + + # Call config target + echo + echo "* Run ${target} on ${arch}/${flavour} ..." + ${kmake} O=build "${env[@]}" "${target}" + + # Move config for further processing + mv build/.config "${tmp_conf_file}" +done + +rc=0 + +if [ "${skip_checks:-}" = "true" ] ; then + echo + echo "Skipping config-check (skip_checks=${skip_checks}) ..." +else + echo + echo "Running config-check for all configurations ..." + fail=0 + for arch_flavour in ${FLAVOURS} ; do + arch=${arch_flavour%%-*} + flavour=${arch_flavour#*-} + tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour} + + echo + echo "* Run config-check for ${arch}-${flavour} ..." + python3 debian/scripts/misc/annotations -f "${annotations_file}" \ + --arch "${arch}" --flavour "${flavour}" --check "${tmp_conf_file}" || \ + fail=$((fail + 1)) + done + + if [ ${fail} -gt 0 ] ; then + rc=1 + echo "ERROR: ${fail} config-check failures detected" >&2 + fi +fi + +if [ ${#warning_partial[@]} -gt 0 ] ; then + rc=1 + echo "ERROR: Config operation not applied to all architectures (skipped ${warning_partial[*]})" >&2 +fi + +# Recreate the annotations file +if [ "${mode}" = "genconfigs" ] ; then + rm -rf CONFIGS + mv "${TMP_DIR}" CONFIGS +else + echo + echo "Importing all configurations ..." + echo + for arch_flavour in ${FLAVOURS} ; do + arch=${arch_flavour%%-*} + flavour=${arch_flavour#*-} + tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour} + + echo "* Import configs for ${arch}-${flavour} ..." + python3 debian/scripts/misc/annotations -f "${annotations_file}" \ + --arch "${arch}" --flavour "${flavour}" --import "${tmp_conf_file}" + done +fi + +exit "${rc}" --- linux-xilinx-6.8.0.orig/debian/scripts/module-inclusion +++ linux-xilinx-6.8.0/debian/scripts/module-inclusion @@ -0,0 +1,104 @@ +#!/bin/bash + +# +# Build a new directory of modules based on an inclusion list. +# The includsion list format must be a bash regular expression. +# +# usage: $0 ROOT INCLUSION_LIST +# example: $0 \ +# debian/build/build-virtual-ALL debian/build/build-virtual \ +# debian.master/control.d/virtual.inclusion-list \ +# virtual.depmap +master=0 +if [ "$1" = "--master" ]; then + master=1 + shift +fi + +ROOT=$1 +NROOT=$2 +ILIST=$3 +DEPMAP=$4 + +tmp="/tmp/module-inclusion.$$" + +# +# Prep a destination directory. +# +mkdir -p ${NROOT} + +{ + # Copy over the framework into the master package. + if [ "$master" -eq 1 ]; then + (cd ${ROOT}; find . ! -name "*.ko" -type f) + fi + + # Copy over modules by name or pattern. + while read -r i + do + # + # 'find' blurts a warning if it cannot find any ko files. + # + case "$i" in + \!*) + (cd ${ROOT}; ${i#!} || true) + ;; + *\**) + (cd ${ROOT}; eval find "${i}" -name "*.ko" || true) + ;; + *) + echo "$i" + ;; + esac + done <"${ILIST}" +} >"$tmp" + +# Copy over the listed modules. +while read i +do + # If this is already moved over, all is good. + if [ -f "${NROOT}/$i" ]; then + : + + # If present in the source, moved it over. + elif [ -f "${ROOT}/$i" ]; then + mkdir -p "${NROOT}/`dirname $i`" + mv "${ROOT}/$i" "${NROOT}/$i" + + # Otherwise, it is missing. + else + echo "Warning: Could not find ${ROOT}/$i" 1>&2 + fi +done <"$tmp" + +# Copy over any dependancies, note if those are missing +# we know they are in a pre-requisite package as they must +# have existed at depmap generation time, and can only have +# moved into a package. +let n=0 || true +while [ -s "$tmp" ] +do + let n="$n+1" || true + [ "$n" = "20" ] && break || true + + echo "NOTE: pass $n: dependency scan" 1>&2 + + while read i + do + grep "^$i " "$DEPMAP" | \ + while read m d + do + if [ -f "${ROOT}/$d" ]; then + echo "NOTE: pass $n: ${i} pulls in ${d}" 1>&2 + echo "$d" + mkdir -p "${NROOT}/`dirname $d`" + mv "${ROOT}/$d" "${NROOT}/$d" + fi + done + done <"$tmp" >"$tmp.new" + mv -f "$tmp.new" "$tmp" +done + +rm -f "$tmp" + +exit 0 --- linux-xilinx-6.8.0.orig/debian/scripts/sign-module +++ linux-xilinx-6.8.0/debian/scripts/sign-module @@ -0,0 +1,40 @@ +#!/bin/bash -eu +# +# Staging drivers must not be signed if they are not listed in a +# signature-inclusion file to prevent loading of 'unsafe' drivers in a +# Secure Boot environment. +# +# Exit with status 0 if the provided module needs to be signed, 1 otherwise +# + +mod=${1} + +# Sign the module if not a staging driver +if [ "${mod/\/drivers\/staging\//}" = "${mod}" ] ; then + exit 0 +fi + +root=$(dirname "$(realpath -e "${0}")")/../.. +. "${root}"/debian/debian.env + +# Collect the signature-inclusion files +sig_incls=() +for d in debian "${DEBIAN}" ; do + if [ -f "${root}"/"${d}"/signature-inclusion ] ; then + sig_incls+=("${root}"/"${d}"/signature-inclusion) + fi +done + +# Sign the module if no signature-inclusion files +if [ ${#sig_incls[@]} -eq 0 ] ; then + exit 0 +fi + +# Sign the module if listed in signature-inclusion files +if grep -qFx "${mod##*/}" "${sig_incls[@]}" ; then + exit 0 +fi + +# Don't sign the module +echo "UBUNTU: Not signing ${1}" +exit 1 --- linux-xilinx-6.8.0.orig/debian/signature-inclusion +++ linux-xilinx-6.8.0/debian/signature-inclusion @@ -0,0 +1,12 @@ +# +# This file lists the staging drivers that are safe for signing +# and loading in a secure boot environment with signed module enforcement. +# +r8188eu.ko +r8192e_pci.ko +r8192u_usb.ko +r8712u.ko +rtllib_crypt_ccmp.ko +rtllib_crypt_tkip.ko +rtllib_crypt_wep.ko +rtllib.ko --- linux-xilinx-6.8.0.orig/debian/snapcraft.mk +++ linux-xilinx-6.8.0/debian/snapcraft.mk @@ -0,0 +1,11 @@ +ifeq ($(ARCH),) + arch := $(shell uname -m | sed -e s/i.86/i386/ -e s/x86_64/amd64/ \ + -e s/arm.*/armhf/ -e s/s390/s390x/ -e s/ppc.*/powerpc/ \ + -e s/aarch64.*/arm64/ ) +else ifeq ($(ARCH),arm) + arch := armhf +else + arch := $(ARCH) +endif +config: + python3 debian/scripts/misc/annotations --export --arch $(arch) --flavour $(flavour) >.config --- linux-xilinx-6.8.0.orig/debian/source/format +++ linux-xilinx-6.8.0/debian/source/format @@ -0,0 +1 @@ +1.0 --- linux-xilinx-6.8.0.orig/debian/source/options +++ linux-xilinx-6.8.0/debian/source/options @@ -0,0 +1,8 @@ +# Ignore vbox symlinks, we will regenerate these at clean (LP:1426113) +## autoreconstruct -- begin +# Ignore any symlinks created since the orig which are rebuilt by reconstruct. +## autoreconstruct -- end + +# force "dpkg-source -I -i" behavior +diff-ignore +tar-ignore --- linux-xilinx-6.8.0.orig/debian/templates/extra.postinst.in +++ linux-xilinx-6.8.0/debian/templates/extra.postinst.in @@ -0,0 +1,20 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" != configure ]; then + exit 0 +fi + +depmod -a -F /boot/System.map-$version $version || true +if [ -d /etc/kernel/postinst.d ]; then + cat - >/usr/lib/linux/triggers/$version </dev/null || true +# +# We should be rebuilding the initramfs here on removal to pare down the +# initramfs if it contains any of the objects we just removed. But people +# commonly remove kernels in order to free space in /boot, and rebuilding the +# initramfs now risks ENOSPC when we are trying to make space. The files we +# leave lying about could be confusing, but we trade that against safety on +# removal. +# +#if [ -d /etc/kernel/postinst.d ]; then +# # We want to behave as if linux-image (without us) was installed, therefore +# # we do not want the postinst support to know we are being removed, claim +# # this is an installation event. +# cat - >/usr/lib/linux/triggers/$version </usr/lib/linux/triggers/$version </dev/null; then + linux-update-symlinks remove $version $image_path +fi + +if [ -d /etc/kernel/postrm.d ]; then + # We cannot trigger ourselves as at the end of this we will no longer + # exist and can no longer respond to the trigger. The trigger would + # then become lost. Therefore we clear any pending trigger and apply + # postrm directly. + if [ -f /usr/lib/linux/triggers/$version ]; then + echo "$0 ... removing pending trigger" + rm -f /usr/lib/linux/triggers/$version + fi + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/postrm.d +fi + +if [ "$1" = purge ]; then + for extra_file in modules.dep modules.isapnpmap modules.pcimap \ + modules.usbmap modules.parportmap \ + modules.generic_string modules.ieee1394map \ + modules.ieee1394map modules.pnpbiosmap \ + modules.alias modules.ccwmap modules.inputmap \ + modules.symbols modules.ofmap \ + modules.seriomap modules.\*.bin \ + modules.softdep modules.devname; do + eval rm -f /lib/modules/$version/$extra_file + done + rmdir /lib/modules/$version || true +fi + +exit 0 --- linux-xilinx-6.8.0.orig/debian/templates/image.preinst.in +++ linux-xilinx-6.8.0/debian/templates/image.preinst.in @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" = abort-upgrade ]; then + exit 0 +fi + +if [ "$1" = install ]; then + # Create a flag file for postinst + mkdir -p /lib/modules/$version + touch /lib/modules/$version/.fresh-install +fi + +if [ -d /etc/kernel/preinst.d ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/preinst.d +fi + +exit 0 --- linux-xilinx-6.8.0.orig/debian/templates/image.prerm.in +++ linux-xilinx-6.8.0/debian/templates/image.prerm.in @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" != remove ]; then + exit 0 +fi + +linux-check-removal $version + +if [ -d /etc/kernel/prerm.d ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/prerm.d +fi + +exit 0 --- linux-xilinx-6.8.0.orig/debian/tests-build/README +++ linux-xilinx-6.8.0/debian/tests-build/README @@ -0,0 +1,21 @@ +Scripts placed in this directory get called one at a time by run-parts(8). +The scripts are expected to perform some sort of sanity checks on the +finished build. Scripts will be called once for each flavour. + +Some environment variables are exported to make life a little easier: + +DPKG_ARCH : The dpkg architecture (e.g. "amd64") +KERN_ARCH : The kernel architecture (e.g. "x86_64") +FLAVOUR : The specific flavour for this run (e.g. "generic") +VERSION : The full version of this build (e.g. 2.6.22-1) +REVISION : The exact revision of this build (e.g. 1.3) +PREV_REVISION : The revision prior to this one +ABI_NUM : The specific ABI number for this build (e.g. 2) +PREV_ABI_NUM : The previous ABI number. Can be the same as ABI_NUM. +BUILD_DIR : The directory where this build took place +INSTALL_DIR : The directory where the package is prepared +SOURCE_DIR : Where the main kernel source is + +Scripts are expected to have a zero exit status when no problems occur, +and non-zero when an error occurs that should stop the build. Scripts +should print whatever info they deem needed to deduce the problem. --- linux-xilinx-6.8.0.orig/debian/tests-build/check-aliases +++ linux-xilinx-6.8.0/debian/tests-build/check-aliases @@ -0,0 +1,26 @@ +#!/usr/bin/perl -w + +my %map; + +print "Checking for dupe aliases in $ENV{'FLAVOUR'}...\n"; + +$aliases = + "$ENV{'INSTALL_DIR'}/lib/modules/$ENV{'VERSION'}-$ENV{'FLAVOUR'}/modules.alias"; + +exit 0 unless (-e $aliases); + +open(ALIASES, "< $aliases") or die "Could not open $aliases"; + +while () { + chomp; + my ($junk, $alias, $module) = split; + + if (defined($map{$alias})) { + printf("%s %20s / %-20s : %s \n", ("$map{$alias}" eq "$module") + ? "INT" : " ", $map{$alias}, $module, $alias); + } else { + $map{$alias} = $module; + } +} + +exit(0); --- linux-xilinx-6.8.0.orig/debian/tests/control +++ linux-xilinx-6.8.0/debian/tests/control @@ -0,0 +1,7 @@ +Tests: rebuild +Depends: @builddeps@, fakeroot +Restrictions: allow-stderr, skippable + +Tests: ubuntu-regression-suite +Depends: build-essential, fakeroot, gcc-multilib [amd64 armhf i386], gdb, git, python3 +Restrictions: allow-stderr, isolation-machine, breaks-testbed, skippable --- linux-xilinx-6.8.0.orig/debian/tests/rebuild +++ linux-xilinx-6.8.0/debian/tests/rebuild @@ -0,0 +1,20 @@ +#!/bin/sh + +# If we are triggering for just linux or linux-meta we know we have +# just built the kernel and there is no point in repeating that +# build, it just wastes time. (LP: #1498862) +build_needed=0 +for trigger in ${ADT_TEST_TRIGGERS:-force} +do + case "$trigger" in + linux/*|linux-lts-*/*|linux-meta*/*|linux-oem*/*|fakeroot/*|gdb/*|git/*|bzr/*|gcc-multilib/*) ;; + *) build_needed=1 ;; + esac +done +if [ "$build_needed" -eq 0 ]; then + echo "rebuild: short circuiting build for '${ADT_TEST_TRIGGERS}'" + exit 77 +fi + +set -e +dpkg-buildpackage -rfakeroot -us -uc -b -Pautopkgtest --- linux-xilinx-6.8.0.orig/debian/tests/ubuntu-regression-suite +++ linux-xilinx-6.8.0/debian/tests/ubuntu-regression-suite @@ -0,0 +1,46 @@ +#!/bin/sh +set -e + +# Only run regression-suite on kernels we can boot in canonistack +source=`dpkg-parsechangelog -SSource` +case $source in + linux|linux-unstable|linux-hwe*|linux-lowlatency*|linux-kvm|linux-oem) + ;; + *) + echo "ubuntu-regression-suite is pointless, if one cannot boot the kernel" + exit 77 + ;; +esac + +# Only run regression-suite if we were requested to +have_meta=0 +for trigger in ${ADT_TEST_TRIGGERS} +do + case "$trigger" in + linux-meta/*|linux-meta-*/*) + have_meta=1 + ;; + esac +done +if [ -n "$ADT_TEST_TRIGGERS" ] && [ "$have_meta" -eq 0 ]; then + echo "ubuntu-regression-suite is not requested, as there is no linux-meta trigger" + exit 77 +fi + +sver=`dpkg-parsechangelog -SVersion` +read x rver x &2 + exit 1 +fi + +git clone --depth=1 -b autotest3 git://git.launchpad.net/~canonical-kernel-team/+git/kernel-testing +git -C kernel-testing/ show HEAD -q +kernel-testing/run-dep8-tests --- linux-xilinx-6.8.0.orig/debian/tools/generic +++ linux-xilinx-6.8.0/debian/tools/generic @@ -0,0 +1,60 @@ +#!/bin/bash +full_version=`uname -r` + +# First check for a fully qualified version. +this="/usr/lib/linux-tools/$full_version/`basename $0`" +if [ -f "$this" ]; then + exec "$this" "$@" +fi + +# Removing flavour from version i.e. generic or server. +flavour_abi=${full_version#*-} +flavour=${flavour_abi#*-} +version=${full_version%-$flavour} +this="$0_$version" +if [ -f "$this" ]; then + exec "$this" "$@" +fi + +# Before saucy kernels we had no flavour linkage. +if dpkg --compare-versions "$version" lt "3.11.0"; then + flavour='' +else + flavour="-$flavour" +fi +# Hint at the cloud tools if they exist (trusty and later) +if dpkg --compare-versions "$version" ge "3.13.0"; then + cld="" +else + cld=":" +fi +# Work out if this is an LTS backport or not. +codename=`lsb_release -cs` +case "$codename" in +precise) base='3.2.0-9999' ;; +trusty) base='3.13.0-9999' ;; +*) base='' ;; +esac +std="" +lts=":" +if [ "$base" != "" ]; then + if dpkg --compare-versions "$version" gt "$base"; then + std=":" + lts="" + fi +fi + +# Give them a hint as to what to install. + echo "WARNING: `basename $0` not found for kernel $version" >&2 + echo "" >&2 + echo " You may need to install the following packages for this specific kernel:" >&2 + echo " linux-tools-$version$flavour" >&2 +$cld echo " linux-cloud-tools-$version$flavour" >&2 + echo "" >&2 + echo " You may also want to install one of the following packages to keep up to date:" >&2 +$std echo " linux-tools$flavour" >&2 +$std $cld echo " linux-cloud-tools$flavour" >&2 +$lts echo " linux-tools$flavour-lts-" >&2 +$lts $cld echo " linux-cloud-tools$flavour-lts-" >&2 + +exit 2 --- linux-xilinx-6.8.0.orig/debian/tools/python-perf.py +++ linux-xilinx-6.8.0/debian/tools/python-perf.py @@ -0,0 +1,32 @@ +import os +import importlib.util +from glob import glob + +class KernelNotFoundError(Exception): + def __init__(self): + kernel_version = os.uname().release + super().__init__(f"WARNING: python perf module not found for kernel {kernel_version}\n\n" + f"You may need to install the following packages for this specific kernel:\n" + f" linux-tools-{kernel_version}-generic\n" + f"You may also want to install of the following package to keep up to date:\n" + f" linux-tools-generic") + +# Extract ABI number from kernel version +def _get_abi_version(): + _kernel_version = os.uname().release + _parts = _kernel_version.split("-") + return "-".join(_parts[:-1]) + +# Load the actual python-perf module for the running kernel +_abi_version = _get_abi_version() +_perf_dir = f"/usr/lib/python3/dist-packages/linux-tools-{_abi_version}" +if not os.path.exists(_perf_dir): + raise KernelNotFoundError() +_perf_lib = glob(os.path.join(_perf_dir, "*.so"))[-1] + +_spec = importlib.util.spec_from_file_location("perf", _perf_lib) +_perf = importlib.util.module_from_spec(_spec) +_spec.loader.exec_module(_perf) + +# Expose the 'perf' module. +__all__ = ['perf'] --- linux-xilinx-6.8.0.orig/debian/v4l2loopback-modules.ignore +++ linux-xilinx-6.8.0/debian/v4l2loopback-modules.ignore @@ -0,0 +1 @@ +v4l2loopback --- linux-xilinx-6.8.0.orig/debian/zfs-modules.ignore +++ linux-xilinx-6.8.0/debian/zfs-modules.ignore @@ -0,0 +1,11 @@ +icp +spl +splat +zavl +zcommon +zfs +zlua +znvpair +zpios +zunicode +zzstd --- linux-xilinx-6.8.0.orig/drivers/Makefile +++ linux-xilinx-6.8.0/drivers/Makefile @@ -66,14 +66,9 @@ # iommu/ comes before gpu as gpu are using iommu controllers obj-y += iommu/ -# gpu/ comes after char for AGP vs DRM startup and after iommu -obj-y += gpu/ obj-$(CONFIG_CONNECTOR) += connector/ -# i810fb depends on char/agp/ -obj-$(CONFIG_FB_I810) += video/fbdev/i810/ - obj-$(CONFIG_PARPORT) += parport/ obj-y += base/ block/ misc/ mfd/ nfc/ obj-$(CONFIG_LIBNVDIMM) += nvdimm/ @@ -85,6 +80,11 @@ obj-y += scsi/ obj-y += nvme/ obj-$(CONFIG_ATA) += ata/ + +# gpu/ comes after char for AGP vs DRM startup and after iommu +obj-y += gpu/ +# i810fb depends on char/agp/ +obj-$(CONFIG_FB_I810) += video/fbdev/i810/ obj-$(CONFIG_TARGET_CORE) += target/ obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_SPI) += spi/ --- linux-xilinx-6.8.0.orig/drivers/accel/habanalabs/common/habanalabs.h +++ linux-xilinx-6.8.0/drivers/accel/habanalabs/common/habanalabs.h @@ -2547,7 +2547,7 @@ * DEVICES */ -#define HL_STR_MAX 32 +#define HL_STR_MAX 64 #define HL_DEV_STS_MAX (HL_DEVICE_STATUS_LAST + 1) --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_drv.c +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_drv.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include @@ -131,22 +131,6 @@ return 0; } -static int ivpu_get_core_clock_rate(struct ivpu_device *vdev, u64 *clk_rate) -{ - int ret; - - ret = ivpu_rpm_get_if_active(vdev); - if (ret < 0) - return ret; - - *clk_rate = ret ? ivpu_hw_reg_pll_freq_get(vdev) : 0; - - if (ret) - ivpu_rpm_put(vdev); - - return 0; -} - static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct ivpu_file_priv *file_priv = file->driver_priv; @@ -170,7 +154,7 @@ args->value = vdev->platform; break; case DRM_IVPU_PARAM_CORE_CLOCK_RATE: - ret = ivpu_get_core_clock_rate(vdev, &args->value); + args->value = ivpu_hw_ratio_to_freq(vdev, vdev->hw->pll.max_ratio); break; case DRM_IVPU_PARAM_NUM_CONTEXTS: args->value = ivpu_get_context_count(vdev); @@ -387,12 +371,15 @@ { int ret; - ivpu_prepare_for_reset(vdev); + /* Save PCI state before powering down as it sometimes gets corrupted if NPU hangs */ + pci_save_state(to_pci_dev(vdev->drm.dev)); ret = ivpu_hw_power_down(vdev); if (ret) ivpu_warn(vdev, "Failed to power down HW: %d\n", ret); + pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); + return ret; } @@ -530,7 +517,7 @@ vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID; vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID; atomic64_set(&vdev->unique_id_counter, 0); - xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC); + xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1); lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key); INIT_LIST_HEAD(&vdev->bo_list); @@ -559,11 +546,11 @@ /* Power up early so the rest of init code can access VPU registers */ ret = ivpu_hw_power_up(vdev); if (ret) - goto err_power_down; + goto err_shutdown; ret = ivpu_mmu_global_context_init(vdev); if (ret) - goto err_power_down; + goto err_shutdown; ret = ivpu_mmu_init(vdev); if (ret) @@ -600,10 +587,8 @@ ivpu_mmu_reserved_context_fini(vdev); err_mmu_gctx_fini: ivpu_mmu_global_context_fini(vdev); -err_power_down: - ivpu_hw_power_down(vdev); - if (IVPU_WA(d3hot_after_power_off)) - pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); +err_shutdown: + ivpu_shutdown(vdev); err_xa_destroy: xa_destroy(&vdev->submitted_jobs_xa); xa_destroy(&vdev->context_xa); @@ -626,9 +611,8 @@ static void ivpu_dev_fini(struct ivpu_device *vdev) { ivpu_pm_disable(vdev); + ivpu_prepare_for_reset(vdev); ivpu_shutdown(vdev); - if (IVPU_WA(d3hot_after_power_off)) - pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); ivpu_jobs_abort_all(vdev); ivpu_job_done_consumer_fini(vdev); --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_drv.h +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_drv.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #ifndef __IVPU_DRV_H__ @@ -87,7 +87,6 @@ struct ivpu_wa_table { bool punit_disabled; bool clear_runtime_mem; - bool d3hot_after_power_off; bool interrupt_clear_with_0; bool disable_clock_relinquish; bool disable_d0i3_msg; --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_hw.h +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_hw.h @@ -21,6 +21,7 @@ u32 (*profiling_freq_get)(struct ivpu_device *vdev); void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable); u32 (*reg_pll_freq_get)(struct ivpu_device *vdev); + u32 (*ratio_to_freq)(struct ivpu_device *vdev, u32 ratio); u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev); u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev); u32 (*reg_telemetry_enable_get)(struct ivpu_device *vdev); @@ -130,6 +131,11 @@ return vdev->hw->ops->reg_pll_freq_get(vdev); }; +static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) +{ + return vdev->hw->ops->ratio_to_freq(vdev, ratio); +} + static inline u32 ivpu_hw_reg_telemetry_offset_get(struct ivpu_device *vdev) { return vdev->hw->ops->reg_telemetry_offset_get(vdev); --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_hw_37xx.c +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_hw_37xx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include "ivpu_drv.h" @@ -75,7 +75,6 @@ { vdev->wa.punit_disabled = false; vdev->wa.clear_runtime_mem = false; - vdev->wa.d3hot_after_power_off = true; REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, BUTTRESS_ALL_IRQ_MASK); if (REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) == BUTTRESS_ALL_IRQ_MASK) { @@ -86,7 +85,6 @@ IVPU_PRINT_WA(punit_disabled); IVPU_PRINT_WA(clear_runtime_mem); - IVPU_PRINT_WA(d3hot_after_power_off); IVPU_PRINT_WA(interrupt_clear_with_0); } @@ -805,12 +803,12 @@ /* Profiling freq - is a debug feature. Unavailable on VPU 37XX. */ } -static u32 ivpu_hw_37xx_pll_to_freq(u32 ratio, u32 config) +static u32 ivpu_hw_37xx_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) { u32 pll_clock = PLL_REF_CLK_FREQ * ratio; u32 cpu_clock; - if ((config & 0xff) == PLL_RATIO_4_3) + if ((vdev->hw->config & 0xff) == PLL_RATIO_4_3) cpu_clock = pll_clock * 2 / 4; else cpu_clock = pll_clock * 2 / 5; @@ -829,7 +827,7 @@ if (!ivpu_is_silicon(vdev)) return PLL_SIMULATION_FREQ; - return ivpu_hw_37xx_pll_to_freq(pll_curr_ratio, vdev->hw->config); + return ivpu_hw_37xx_ratio_to_freq(vdev, pll_curr_ratio); } static u32 ivpu_hw_37xx_reg_telemetry_offset_get(struct ivpu_device *vdev) @@ -1052,6 +1050,7 @@ .profiling_freq_get = ivpu_hw_37xx_profiling_freq_get, .profiling_freq_drive = ivpu_hw_37xx_profiling_freq_drive, .reg_pll_freq_get = ivpu_hw_37xx_reg_pll_freq_get, + .ratio_to_freq = ivpu_hw_37xx_ratio_to_freq, .reg_telemetry_offset_get = ivpu_hw_37xx_reg_telemetry_offset_get, .reg_telemetry_size_get = ivpu_hw_37xx_reg_telemetry_size_get, .reg_telemetry_enable_get = ivpu_hw_37xx_reg_telemetry_enable_get, --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_hw_40xx.c +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_hw_40xx.c @@ -980,6 +980,11 @@ return PLL_RATIO_TO_FREQ(pll_curr_ratio); } +static u32 ivpu_hw_40xx_ratio_to_freq(struct ivpu_device *vdev, u32 ratio) +{ + return PLL_RATIO_TO_FREQ(ratio); +} + static u32 ivpu_hw_40xx_reg_telemetry_offset_get(struct ivpu_device *vdev) { return REGB_RD32(VPU_40XX_BUTTRESS_VPU_TELEMETRY_OFFSET); @@ -1230,6 +1235,7 @@ .profiling_freq_get = ivpu_hw_40xx_profiling_freq_get, .profiling_freq_drive = ivpu_hw_40xx_profiling_freq_drive, .reg_pll_freq_get = ivpu_hw_40xx_reg_pll_freq_get, + .ratio_to_freq = ivpu_hw_40xx_ratio_to_freq, .reg_telemetry_offset_get = ivpu_hw_40xx_reg_telemetry_offset_get, .reg_telemetry_size_get = ivpu_hw_40xx_reg_telemetry_size_get, .reg_telemetry_enable_get = ivpu_hw_40xx_reg_telemetry_enable_get, --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_ipc.c +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_ipc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include @@ -501,7 +501,11 @@ spin_lock_init(&ipc->cons_lock); INIT_LIST_HEAD(&ipc->cons_list); INIT_LIST_HEAD(&ipc->cb_msg_list); - drmm_mutex_init(&vdev->drm, &ipc->lock); + ret = drmm_mutex_init(&vdev->drm, &ipc->lock); + if (ret) { + ivpu_err(vdev, "Failed to initialize ipc->lock, ret %d\n", ret); + goto err_free_rx; + } ivpu_ipc_reset(vdev); return 0; --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_mmu.c +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_mmu.c @@ -278,7 +278,7 @@ case IVPU_MMU_EVT_F_VMS_FETCH: return "Fetch of VMS caused external abort"; default: - return "Unknown CMDQ command"; + return "Unknown event"; } } @@ -286,15 +286,15 @@ { switch (err) { case IVPU_MMU_CERROR_NONE: - return "No CMDQ Error"; + return "No error"; case IVPU_MMU_CERROR_ILL: return "Illegal command"; case IVPU_MMU_CERROR_ABT: - return "External abort on CMDQ read"; + return "External abort on command queue read"; case IVPU_MMU_CERROR_ATC_INV_SYNC: return "Sync failed to complete ATS invalidation"; default: - return "Unknown CMDQ Error"; + return "Unknown error"; } } --- linux-xilinx-6.8.0.orig/drivers/accel/ivpu/ivpu_pm.c +++ linux-xilinx-6.8.0/drivers/accel/ivpu/ivpu_pm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #include @@ -58,14 +58,11 @@ { int ret; - /* Save PCI state before powering down as it sometimes gets corrupted if NPU hangs */ - pci_save_state(to_pci_dev(vdev->drm.dev)); + ivpu_prepare_for_reset(vdev); ret = ivpu_shutdown(vdev); if (ret) - ivpu_err(vdev, "Failed to shutdown VPU: %d\n", ret); - - pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); + ivpu_err(vdev, "Failed to shutdown NPU: %d\n", ret); return ret; } @@ -74,10 +71,10 @@ { int ret; - pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0); +retry: pci_restore_state(to_pci_dev(vdev->drm.dev)); + pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0); -retry: ret = ivpu_hw_power_up(vdev); if (ret) { ivpu_err(vdev, "Failed to power up HW: %d\n", ret); @@ -100,6 +97,7 @@ ivpu_mmu_disable(vdev); err_power_down: ivpu_hw_power_down(vdev); + pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot); if (!ivpu_fw_is_cold_boot(vdev)) { ivpu_pm_prepare_cold_boot(vdev); --- linux-xilinx-6.8.0.orig/drivers/accessibility/speakup/main.c +++ linux-xilinx-6.8.0/drivers/accessibility/speakup/main.c @@ -574,7 +574,7 @@ } attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr); buf[cnt++] = attr_ch; - while (tmpx < vc->vc_cols - 1) { + while (tmpx < vc->vc_cols - 1 && cnt < ARRAY_SIZE(buf) - 1) { tmp_pos += 2; tmpx++; ch = get_char(vc, (u_short *)tmp_pos, &temp); --- linux-xilinx-6.8.0.orig/drivers/accessibility/speakup/synth.c +++ linux-xilinx-6.8.0/drivers/accessibility/speakup/synth.c @@ -208,8 +208,10 @@ wake_up_process(speakup_task); } -void synth_write(const char *buf, size_t count) +void synth_write(const char *_buf, size_t count) { + const unsigned char *buf = (const unsigned char *) _buf; + while (count--) synth_buffer_add(*buf++); synth_start(); --- linux-xilinx-6.8.0.orig/drivers/acpi/ac.c +++ linux-xilinx-6.8.0/drivers/acpi/ac.c @@ -145,7 +145,7 @@ dev_name(&adev->dev), event, (u32) ac->state); acpi_notifier_call_chain(adev, event, (u32) ac->state); - kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE); + power_supply_changed(ac->charger); } } @@ -268,7 +268,7 @@ if (acpi_ac_get_state(ac)) return 0; if (old_state != ac->state) - kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE); + power_supply_changed(ac->charger); return 0; } --- linux-xilinx-6.8.0.orig/drivers/acpi/acpi_ipmi.c +++ linux-xilinx-6.8.0/drivers/acpi/acpi_ipmi.c @@ -22,6 +22,8 @@ /* the IPMI timeout is 5s */ #define IPMI_TIMEOUT (5000) #define ACPI_IPMI_MAX_MSG_LENGTH 64 +/* 2s should be suffient for SMI being selected */ +#define ACPI_IPMI_SMI_SELECTION_TIMEOUT (2 * HZ) struct acpi_ipmi_device { /* the device list attached to driver_data.ipmi_devices */ @@ -54,6 +56,7 @@ * to this selected global IPMI system interface. */ struct acpi_ipmi_device *selected_smi; + struct completion smi_selection_done; }; struct acpi_ipmi_msg { @@ -463,8 +466,10 @@ if (temp->handle == handle) goto err_lock; } - if (!driver_data.selected_smi) + if (!driver_data.selected_smi) { driver_data.selected_smi = ipmi_device; + complete(&driver_data.smi_selection_done); + } list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices); mutex_unlock(&driver_data.ipmi_lock); @@ -578,6 +583,20 @@ return status; } +int acpi_wait_for_acpi_ipmi(void) +{ + long ret; + + ret = wait_for_completion_interruptible_timeout(&driver_data.smi_selection_done, + ACPI_IPMI_SMI_SELECTION_TIMEOUT); + + if (ret <= 0) + return -ETIMEDOUT; + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_wait_for_acpi_ipmi); + static int __init acpi_ipmi_init(void) { int result; @@ -586,6 +605,8 @@ if (acpi_disabled) return 0; + init_completion(&driver_data.smi_selection_done); + status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_IPMI, &acpi_ipmi_space_handler, --- linux-xilinx-6.8.0.orig/drivers/acpi/acpi_lpss.c +++ linux-xilinx-6.8.0/drivers/acpi/acpi_lpss.c @@ -325,6 +325,7 @@ static const struct property_entry bsw_spi_properties[] = { PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BSW_SSP), + PROPERTY_ENTRY_U32("num-cs", 2), { } }; --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/Makefile +++ linux-xilinx-6.8.0/drivers/acpi/acpica/Makefile @@ -5,6 +5,7 @@ ccflags-y := -D_LINUX -DBUILDING_ACPICA ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT +CFLAGS_tbfind.o += $(call cc-disable-warning, stringop-truncation) # use acpi.o to put all files here into acpi.o modparam namespace obj-y += acpi.o --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/acevents.h +++ linux-xilinx-6.8.0/drivers/acpi/acpica/acevents.h @@ -191,6 +191,10 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, acpi_adr_space_type space_id, u32 function); +void +acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *node, + acpi_adr_space_type space_id); + acpi_status acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function); --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/dbnames.c +++ linux-xilinx-6.8.0/drivers/acpi/acpica/dbnames.c @@ -550,8 +550,12 @@ ACPI_FREE(buffer.pointer); buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - acpi_evaluate_object(obj_handle, NULL, NULL, &buffer); - + status = acpi_evaluate_object(obj_handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + acpi_os_printf("Could Not evaluate object %p\n", + obj_handle); + return (AE_OK); + } /* * Since this is a field unit, surround the output in braces */ --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/dswexec.c +++ linux-xilinx-6.8.0/drivers/acpi/acpica/dswexec.c @@ -397,11 +397,11 @@ /* Resolve all operands */ + union acpi_operand_object **stack_ptr = NULL; + if (walk_state->num_operands > 0) + stack_ptr = ACPI_WALK_OPERANDS; status = acpi_ex_resolve_operands(walk_state->opcode, - &(walk_state-> - operands - [walk_state-> - num_operands - 1]), + stack_ptr, walk_state); } --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/evregion.c +++ linux-xilinx-6.8.0/drivers/acpi/acpica/evregion.c @@ -20,10 +20,6 @@ /* Local prototypes */ -static void -acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, - acpi_adr_space_type space_id); - static acpi_status acpi_ev_reg_run(acpi_handle obj_handle, u32 level, void *context, void **return_value); @@ -818,7 +814,7 @@ * ******************************************************************************/ -static void +void acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node, acpi_adr_space_type space_id) { --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/evxfregn.c +++ linux-xilinx-6.8.0/drivers/acpi/acpica/evxfregn.c @@ -306,3 +306,57 @@ } ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods) + +/******************************************************************************* + * + * FUNCTION: acpi_execute_orphan_reg_method + * + * PARAMETERS: device - Handle for the device + * space_id - The address space ID + * + * RETURN: Status + * + * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI + * device. This is a _REG method that has no corresponding region + * within the device's scope. + * + ******************************************************************************/ +acpi_status +acpi_execute_orphan_reg_method(acpi_handle device, acpi_adr_space_type space_id) +{ + struct acpi_namespace_node *node; + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_execute_orphan_reg_method); + + /* Parameter validation */ + + if (!device) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Convert and validate the device handle */ + + node = acpi_ns_validate_handle(device); + if (node) { + + /* + * If an "orphan" _REG method is present in the device's scope + * for the given address space ID, run it. + */ + + acpi_ev_execute_orphan_reg_method(node, space_id); + } else { + status = AE_BAD_PARAMETER; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_execute_orphan_reg_method) --- linux-xilinx-6.8.0.orig/drivers/acpi/acpica/exregion.c +++ linux-xilinx-6.8.0/drivers/acpi/acpica/exregion.c @@ -44,7 +44,6 @@ struct acpi_mem_mapping *mm = mem_info->cur_mm; u32 length; acpi_size map_length; - acpi_size page_boundary_map_length; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif @@ -138,26 +137,8 @@ map_length = (acpi_size) ((mem_info->address + mem_info->length) - address); - /* - * If mapping the entire remaining portion of the region will cross - * a page boundary, just map up to the page boundary, do not cross. - * On some systems, crossing a page boundary while mapping regions - * can cause warnings if the pages have different attributes - * due to resource management. - * - * This has the added benefit of constraining a single mapping to - * one page, which is similar to the original code that used a 4k - * maximum window. - */ - page_boundary_map_length = (acpi_size) - (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address); - if (page_boundary_map_length == 0) { - page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; - } - - if (map_length > page_boundary_map_length) { - map_length = page_boundary_map_length; - } + if (map_length > ACPI_DEFAULT_PAGE_SIZE) + map_length = ACPI_DEFAULT_PAGE_SIZE; /* Create a new mapping starting at the address given */ --- linux-xilinx-6.8.0.orig/drivers/acpi/bus.c +++ linux-xilinx-6.8.0/drivers/acpi/bus.c @@ -316,9 +316,14 @@ capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT; if (IS_ENABLED(CONFIG_ACPI_PROCESSOR)) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT; + if (IS_ENABLED(CONFIG_ACPI_THERMAL)) + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FAST_THERMAL_SAMPLING_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT; capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT; + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_OVER_16_PSTATES_SUPPORT; + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GED_SUPPORT; + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_IRQ_RESOURCE_SOURCE_SUPPORT; if (IS_ENABLED(CONFIG_ACPI_PRMT)) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT; if (IS_ENABLED(CONFIG_ACPI_FFH)) --- linux-xilinx-6.8.0.orig/drivers/acpi/cppc_acpi.c +++ linux-xilinx-6.8.0/drivers/acpi/cppc_acpi.c @@ -166,6 +166,13 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf); show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); +/* Check for valid access_width, otherwise, fallback to using bit_width */ +#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width) + +/* Shift and apply the mask for CPC reads/writes */ +#define MASK_VAL(reg, val) (((val) >> (reg)->bit_offset) & \ + GENMASK(((reg)->bit_width) - 1, 0)) + static ssize_t show_feedback_ctrs(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -780,6 +787,7 @@ } else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (gas_t->address) { void __iomem *addr; + size_t access_width; if (!osc_cpc_flexible_adr_space_confirmed) { pr_debug("Flexible address space capability not supported\n"); @@ -787,7 +795,8 @@ goto out_free; } - addr = ioremap(gas_t->address, gas_t->bit_width/8); + access_width = GET_BIT_WIDTH(gas_t) / 8; + addr = ioremap(gas_t->address, access_width); if (!addr) goto out_free; cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr; @@ -983,6 +992,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) { void __iomem *vaddr = NULL; + int size; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; @@ -992,14 +1002,14 @@ } *val = 0; + size = GET_BIT_WIDTH(reg); if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - u32 width = 8 << (reg->access_width - 1); u32 val_u32; acpi_status status; status = acpi_os_read_port((acpi_io_address)reg->address, - &val_u32, width); + &val_u32, size); if (ACPI_FAILURE(status)) { pr_debug("Error: Failed to read SystemIO port %llx\n", reg->address); @@ -1008,17 +1018,24 @@ *val = val_u32; return 0; - } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_read_ffh(cpu, reg, val); else return acpi_os_read_memory((acpi_physical_address)reg->address, - val, reg->bit_width); + val, size); - switch (reg->bit_width) { + switch (size) { case 8: *val = readb_relaxed(vaddr); break; @@ -1032,27 +1049,37 @@ *val = readq_relaxed(vaddr); break; default: - pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot read %u bit width from system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n", + size, pcc_ss_id); + } return -EFAULT; } + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + *val = MASK_VAL(reg, *val); + return 0; } static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) { int ret_val = 0; + int size; void __iomem *vaddr = NULL; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; + size = GET_BIT_WIDTH(reg); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { - u32 width = 8 << (reg->access_width - 1); acpi_status status; status = acpi_os_write_port((acpi_io_address)reg->address, - (u32)val, width); + (u32)val, size); if (ACPI_FAILURE(status)) { pr_debug("Error: Failed to write SystemIO port %llx\n", reg->address); @@ -1060,17 +1087,27 @@ } return 0; - } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) { + /* + * For registers in PCC space, the register size is determined + * by the bit width field; the access size is used to indicate + * the PCC subspace id. + */ + size = reg->bit_width; vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); + } else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_write_ffh(cpu, reg, val); else return acpi_os_write_memory((acpi_physical_address)reg->address, - val, reg->bit_width); + val, size); + + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + val = MASK_VAL(reg, val); - switch (reg->bit_width) { + switch (size) { case 8: writeb_relaxed(val, vaddr); break; @@ -1084,8 +1121,13 @@ writeq_relaxed(val, vaddr); break; default: - pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", - reg->bit_width, pcc_ss_id); + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + pr_debug("Error: Cannot write %u bit width to system memory: 0x%llx\n", + size, reg->address); + } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { + pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n", + size, pcc_ss_id); + } ret_val = -EFAULT; break; } --- linux-xilinx-6.8.0.orig/drivers/acpi/ec.c +++ linux-xilinx-6.8.0/drivers/acpi/ec.c @@ -1333,10 +1333,13 @@ if (ec->busy_polling || bits > 8) acpi_ec_burst_enable(ec); - for (i = 0; i < bytes; ++i, ++address, ++value) + for (i = 0; i < bytes; ++i, ++address, ++value) { result = (function == ACPI_READ) ? acpi_ec_read(ec, address, value) : acpi_ec_write(ec, address, *value); + if (result < 0) + break; + } if (ec->busy_polling || bits > 8) acpi_ec_burst_disable(ec); @@ -1348,8 +1351,10 @@ return AE_NOT_FOUND; case -ETIME: return AE_TIME; - default: + case 0: return AE_OK; + default: + return AE_ERROR; } } @@ -1482,13 +1487,14 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, bool call_reg) { + acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle; acpi_status status; acpi_ec_start(ec, false); if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { acpi_ec_enter_noirq(ec); - status = acpi_install_address_space_handler_no_reg(ec->handle, + status = acpi_install_address_space_handler_no_reg(scope_handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, NULL, ec); @@ -1497,11 +1503,13 @@ return -ENODEV; } set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); - ec->address_space_handler_holder = ec->handle; } if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) { - acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC); + acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC); + if (scope_handle != ec->handle) + acpi_execute_orphan_reg_method(ec->handle, ACPI_ADR_SPACE_EC); + set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags); } @@ -1553,10 +1561,13 @@ static void ec_remove_handlers(struct acpi_ec *ec) { + acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle; + if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { if (ACPI_FAILURE(acpi_remove_address_space_handler( - ec->address_space_handler_holder, - ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) + scope_handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler))) pr_err("failed to remove space handler\n"); clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); } @@ -1595,14 +1606,18 @@ { int ret; - ret = ec_install_handlers(ec, device, call_reg); - if (ret) - return ret; - /* First EC capable of handling transactions */ if (!first_ec) first_ec = ec; + ret = ec_install_handlers(ec, device, call_reg); + if (ret) { + if (ec == first_ec) + first_ec = NULL; + + return ret; + } + pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr, ec->data_addr); --- linux-xilinx-6.8.0.orig/drivers/acpi/internal.h +++ linux-xilinx-6.8.0/drivers/acpi/internal.h @@ -184,7 +184,6 @@ struct acpi_ec { acpi_handle handle; - acpi_handle address_space_handler_holder; int gpe; int irq; unsigned long command_addr; @@ -301,5 +300,10 @@ void acpi_mipi_scan_crs_csi2(void); void acpi_mipi_init_crs_csi2_swnodes(void); void acpi_mipi_crs_csi2_cleanup(void); +#ifdef CONFIG_X86 +bool acpi_graph_ignore_port(acpi_handle handle); +#else +static inline bool acpi_graph_ignore_port(acpi_handle handle) { return false; } +#endif #endif /* _ACPI_INTERNAL_H_ */ --- linux-xilinx-6.8.0.orig/drivers/acpi/mipi-disco-img.c +++ linux-xilinx-6.8.0/drivers/acpi/mipi-disco-img.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include @@ -723,3 +724,83 @@ list_for_each_entry_safe(csi2, csi2_tmp, &acpi_mipi_crs_csi2_list, entry) acpi_mipi_del_crs_csi2(csi2); } + +#ifdef CONFIG_X86 +#include +#include + +/* CPU matches for Dell generations with broken ACPI MIPI DISCO info */ +static const struct x86_cpu_id dell_broken_mipi_disco_cpu_gens[] = { + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, NULL), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, NULL), + {} +}; + +static const char *strnext(const char *s1, const char *s2) +{ + s1 = strstr(s1, s2); + + if (!s1) + return NULL; + + return s1 + strlen(s2); +} + +/** + * acpi_graph_ignore_port - Tell whether a port node should be ignored + * @handle: The ACPI handle of the node (which may be a port node) + * + * Return: true if a port node should be ignored and the data to that should + * come from other sources instead (Windows ACPI definitions and + * ipu-bridge). This is currently used to ignore bad port nodes related to IPU6 + * ("IPU?") and camera sensor devices ("LNK?") in certain Dell systems with + * Intel VSC. + */ +bool acpi_graph_ignore_port(acpi_handle handle) +{ + const char *path = NULL, *orig_path; + static bool dmi_tested, ignore_port; + + if (!dmi_tested) { + if (dmi_name_in_vendors("Dell Inc.") && + x86_match_cpu(dell_broken_mipi_disco_cpu_gens)) + ignore_port = true; + + dmi_tested = true; + } + + if (!ignore_port) + return false; + + /* Check if the device is either "IPU" or "LNK" (sensor). */ + orig_path = acpi_handle_path(handle); + if (!orig_path) + return false; + path = strnext(orig_path, "IPU"); + if (!path) + path = strnext(orig_path, "LNK"); + if (!path) + goto out_free; + + if (!(isdigit(path[0]) && path[1] == '.')) + goto out_free; + + /* Check if the node has a "PRT" prefix. */ + path = strnext(path, "PRT"); + if (path && isdigit(path[0]) && !path[1]) { + acpi_handle_debug(handle, "ignoring data node\n"); + + kfree(orig_path); + return true; + } + +out_free: + kfree(orig_path); + return false; +} +#endif --- linux-xilinx-6.8.0.orig/drivers/acpi/numa/hmat.c +++ linux-xilinx-6.8.0/drivers/acpi/numa/hmat.c @@ -59,9 +59,8 @@ }; enum { - NODE_ACCESS_CLASS_0 = 0, - NODE_ACCESS_CLASS_1, - NODE_ACCESS_CLASS_GENPORT_SINK, + NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL = ACCESS_COORDINATE_MAX, + NODE_ACCESS_CLASS_GENPORT_SINK_CPU, NODE_ACCESS_CLASS_MAX, }; @@ -127,7 +126,8 @@ /** * acpi_get_genport_coordinates - Retrieve the access coordinates for a generic port * @uid: ACPI unique id - * @coord: The access coordinates written back out for the generic port + * @coord: The access coordinates written back out for the generic port. + * Expect 2 levels array. * * Return: 0 on success. Errno on failure. * @@ -143,7 +143,10 @@ if (!target) return -ENOENT; - *coord = target->coord[NODE_ACCESS_CLASS_GENPORT_SINK]; + coord[ACCESS_COORDINATE_LOCAL] = + target->coord[NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL]; + coord[ACCESS_COORDINATE_CPU] = + target->coord[NODE_ACCESS_CLASS_GENPORT_SINK_CPU]; return 0; } @@ -374,11 +377,11 @@ if (target && target->processor_pxm == init_pxm) { hmat_update_target_access(target, type, value, - NODE_ACCESS_CLASS_0); + ACCESS_COORDINATE_LOCAL); /* If the node has a CPU, update access 1 */ if (node_state(pxm_to_node(init_pxm), N_CPU)) hmat_update_target_access(target, type, value, - NODE_ACCESS_CLASS_1); + ACCESS_COORDINATE_CPU); } } @@ -697,7 +700,8 @@ int i; /* Don't update for generic port if there's no device handle */ - if (access == NODE_ACCESS_CLASS_GENPORT_SINK && + if ((access == NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL || + access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU) && !(*(u16 *)target->gen_port_device_handle)) return; @@ -709,7 +713,8 @@ */ if (target->processor_pxm != PXM_INVAL) { cpu_nid = pxm_to_node(target->processor_pxm); - if (access == 0 || node_state(cpu_nid, N_CPU)) { + if (access == ACCESS_COORDINATE_LOCAL || + node_state(cpu_nid, N_CPU)) { set_bit(target->processor_pxm, p_nodes); return; } @@ -737,7 +742,9 @@ list_for_each_entry(initiator, &initiators, node) { u32 value; - if (access == 1 && !initiator->has_cpu) { + if ((access == ACCESS_COORDINATE_CPU || + access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU) && + !initiator->has_cpu) { clear_bit(initiator->processor_pxm, p_nodes); continue; } @@ -770,20 +777,24 @@ } } -static void hmat_register_generic_target_initiators(struct memory_target *target) +static void hmat_update_generic_target(struct memory_target *target) { static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); - __hmat_register_target_initiators(target, p_nodes, - NODE_ACCESS_CLASS_GENPORT_SINK); + hmat_update_target_attrs(target, p_nodes, + NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL); + hmat_update_target_attrs(target, p_nodes, + NODE_ACCESS_CLASS_GENPORT_SINK_CPU); } static void hmat_register_target_initiators(struct memory_target *target) { static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); - __hmat_register_target_initiators(target, p_nodes, 0); - __hmat_register_target_initiators(target, p_nodes, 1); + __hmat_register_target_initiators(target, p_nodes, + ACCESS_COORDINATE_LOCAL); + __hmat_register_target_initiators(target, p_nodes, + ACCESS_COORDINATE_CPU); } static void hmat_register_target_cache(struct memory_target *target) @@ -835,7 +846,7 @@ */ mutex_lock(&target_lock); if (*(u16 *)target->gen_port_device_handle) { - hmat_register_generic_target_initiators(target); + hmat_update_generic_target(target); target->registered = true; } mutex_unlock(&target_lock); @@ -854,8 +865,8 @@ if (!target->registered) { hmat_register_target_initiators(target); hmat_register_target_cache(target); - hmat_register_target_perf(target, NODE_ACCESS_CLASS_0); - hmat_register_target_perf(target, NODE_ACCESS_CLASS_1); + hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL); + hmat_register_target_perf(target, ACCESS_COORDINATE_CPU); target->registered = true; } mutex_unlock(&target_lock); @@ -927,7 +938,7 @@ return NOTIFY_OK; mutex_lock(&target_lock); - hmat_update_target_attrs(target, p_nodes, 1); + hmat_update_target_attrs(target, p_nodes, ACCESS_COORDINATE_CPU); mutex_unlock(&target_lock); perf = &target->coord[1]; --- linux-xilinx-6.8.0.orig/drivers/acpi/numa/srat.c +++ linux-xilinx-6.8.0/drivers/acpi/numa/srat.c @@ -206,6 +206,11 @@ return acpi_numa < 0; } +__weak int __init numa_fill_memblks(u64 start, u64 end) +{ + return NUMA_NO_MEMBLK; +} + #if defined(CONFIG_X86) || defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH) /* * Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for --- linux-xilinx-6.8.0.orig/drivers/acpi/osi.c +++ linux-xilinx-6.8.0/drivers/acpi/osi.c @@ -444,6 +444,77 @@ }, /* + * The following Lenovo models have a broken workaround in the + * acpi_video backlight implementation to meet the Windows 8 + * requirement of 101 backlight levels. Reverting to pre-Win8 + * behavior fixes the problem. + */ + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad L430", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad T430", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad T430s", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad T530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad W530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad X1 Carbon", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad X230", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad Edge E330", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E330"), + }, + }, + + /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. * Linux ignores it, except for the machines enumerated below. */ --- linux-xilinx-6.8.0.orig/drivers/acpi/processor_idle.c +++ linux-xilinx-6.8.0/drivers/acpi/processor_idle.c @@ -16,7 +16,6 @@ #include #include #include /* need_resched() */ -#include #include #include #include @@ -386,25 +385,24 @@ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1); } -static int acpi_cst_latency_cmp(const void *a, const void *b) +static void acpi_cst_latency_sort(struct acpi_processor_cx *states, size_t length) { - const struct acpi_processor_cx *x = a, *y = b; + int i, j, k; - if (!(x->valid && y->valid)) - return 0; - if (x->latency > y->latency) - return 1; - if (x->latency < y->latency) - return -1; - return 0; -} -static void acpi_cst_latency_swap(void *a, void *b, int n) -{ - struct acpi_processor_cx *x = a, *y = b; + for (i = 1; i < length; i++) { + if (!states[i].valid) + continue; - if (!(x->valid && y->valid)) - return; - swap(x->latency, y->latency); + for (j = i - 1, k = i; j >= 0; j--) { + if (!states[j].valid) + continue; + + if (states[j].latency > states[k].latency) + swap(states[j].latency, states[k].latency); + + k = j; + } + } } static int acpi_processor_power_verify(struct acpi_processor *pr) @@ -449,10 +447,7 @@ if (buggy_latency) { pr_notice("FW issue: working around C-state latencies out of order\n"); - sort(&pr->power.states[1], max_cstate, - sizeof(struct acpi_processor_cx), - acpi_cst_latency_cmp, - acpi_cst_latency_swap); + acpi_cst_latency_sort(&pr->power.states[1], max_cstate); } lapic_timer_propagate_broadcast(pr); @@ -1430,6 +1425,8 @@ acpi_processor_registered--; if (acpi_processor_registered == 0) cpuidle_unregister_driver(&acpi_idle_driver); + + kfree(dev); } pr->flags.power_setup_done = 0; --- linux-xilinx-6.8.0.orig/drivers/acpi/property.c +++ linux-xilinx-6.8.0/drivers/acpi/property.c @@ -80,6 +80,9 @@ struct acpi_data_node *dn; bool result; + if (acpi_graph_ignore_port(handle)) + return false; + dn = kzalloc(sizeof(*dn), GFP_KERNEL); if (!dn) return false; --- linux-xilinx-6.8.0.orig/drivers/acpi/resource.c +++ linux-xilinx-6.8.0/drivers/acpi/resource.c @@ -490,6 +490,13 @@ }, }, { + /* Asus ExpertBook B2502FBA */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B2502FBA"), + }, + }, + { /* Asus Vivobook E1504GA */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), @@ -504,12 +511,31 @@ }, }, { + /* Asus Vivobook Pro N6506MV */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "N6506MV"), + }, + }, + { /* LG Electronics 17U70P */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), DMI_MATCH(DMI_BOARD_NAME, "17U70P"), }, }, + { + /* TongFang GXxHRXx/TUXEDO InfinityBook Pro Gen9 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"), + }, + }, + { + /* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), + }, + }, { } }; @@ -520,6 +546,12 @@ */ static const struct dmi_system_id irq1_edge_low_force_override[] = { { + /* XMG APEX 17 (M23) */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxBGxx"), + }, + }, + { /* TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD */ .matches = { DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"), @@ -588,6 +620,27 @@ DMI_MATCH(DMI_BOARD_NAME, "GM5RGEE0016COM"), }, }, + { + /* Lunnen Ground 15 / AMD Ryzen 5 5500U */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"), + DMI_MATCH(DMI_BOARD_NAME, "LLL5DAW"), + }, + }, + { + /* Lunnen Ground 16 / AMD Ryzen 7 5800U */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"), + DMI_MATCH(DMI_BOARD_NAME, "LL6FA"), + }, + }, + { + /* MAIBENBEN X577 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"), + DMI_MATCH(DMI_BOARD_NAME, "X577"), + }, + }, { } }; --- linux-xilinx-6.8.0.orig/drivers/acpi/sbs.c +++ linux-xilinx-6.8.0/drivers/acpi/sbs.c @@ -610,7 +610,7 @@ if (sbs->charger_exists) { acpi_ac_get_present(sbs); if (sbs->charger_present != saved_charger_state) - kobject_uevent(&sbs->charger->dev.kobj, KOBJ_CHANGE); + power_supply_changed(sbs->charger); } if (sbs->manager_present) { @@ -622,7 +622,7 @@ acpi_battery_read(bat); if (saved_battery_state == bat->present) continue; - kobject_uevent(&bat->bat->dev.kobj, KOBJ_CHANGE); + power_supply_changed(bat->bat); } } } --- linux-xilinx-6.8.0.orig/drivers/acpi/scan.c +++ linux-xilinx-6.8.0/drivers/acpi/scan.c @@ -314,18 +314,14 @@ * again). */ if (adev->handler) { - dev_warn(&adev->dev, "Already enumerated\n"); - return -EALREADY; + dev_dbg(&adev->dev, "Already enumerated\n"); + return 0; } error = acpi_bus_scan(adev->handle); if (error) { dev_warn(&adev->dev, "Namespace scan failure\n"); return error; } - if (!adev->handler) { - dev_warn(&adev->dev, "Enumeration failure\n"); - error = -ENODEV; - } } else { error = acpi_scan_device_not_enumerated(adev); } @@ -798,6 +794,7 @@ "INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */ "INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */ "INTC100A", /* IVSC (RPL) driver must be loaded to allow i2c access to camera sensors */ + "INTC10CF", /* IVSC (MTL) driver must be loaded to allow i2c access to camera sensors */ NULL }; @@ -1806,7 +1803,8 @@ if (dep->honor_dep) adev->flags.honor_deps = 1; - adev->dep_unmet++; + if (!dep->met) + adev->dep_unmet++; } } } --- linux-xilinx-6.8.0.orig/drivers/acpi/sleep.c +++ linux-xilinx-6.8.0/drivers/acpi/sleep.c @@ -385,18 +385,6 @@ DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"), }, }, - /* - * ASUS B1400CEAE hangs on resume from suspend (see - * https://bugzilla.kernel.org/show_bug.cgi?id=215742). - */ - { - .callback = init_default_s3, - .ident = "ASUS B1400CEAE", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK B1400CEAE"), - }, - }, {}, }; --- linux-xilinx-6.8.0.orig/drivers/acpi/thermal.c +++ linux-xilinx-6.8.0/drivers/acpi/thermal.c @@ -167,11 +167,17 @@ static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) { + int temp; + if (temp_deci_k == THERMAL_TEMP_INVALID) return THERMAL_TEMP_INVALID; - return deci_kelvin_to_millicelsius_with_offset(temp_deci_k, + temp = deci_kelvin_to_millicelsius_with_offset(temp_deci_k, tz->kelvin_offset); + if (temp <= 0) + return THERMAL_TEMP_INVALID; + + return temp; } static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) --- linux-xilinx-6.8.0.orig/drivers/acpi/utils.c +++ linux-xilinx-6.8.0/drivers/acpi/utils.c @@ -559,7 +559,7 @@ * * Caller must free the returned buffer */ -static char *acpi_handle_path(acpi_handle handle) +char *acpi_handle_path(acpi_handle handle) { struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER, --- linux-xilinx-6.8.0.orig/drivers/acpi/video_detect.c +++ linux-xilinx-6.8.0/drivers/acpi/video_detect.c @@ -499,6 +499,14 @@ }, { .callback = video_detect_force_native, + /* Lenovo Slim 7 16ARH7 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82UX"), + }, + }, + { + .callback = video_detect_force_native, /* Lenovo ThinkPad X131e (3371 AMD version) */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), @@ -894,6 +902,7 @@ static DEFINE_MUTEX(init_mutex); static bool nvidia_wmi_ec_present; static bool apple_gmux_present; + static bool dell_uart_backlight_present; static bool native_available; static bool init_done; static long video_caps; @@ -908,6 +917,7 @@ &video_caps, NULL); nvidia_wmi_ec_present = nvidia_wmi_ec_supported(); apple_gmux_present = apple_gmux_detect(NULL, NULL); + dell_uart_backlight_present = acpi_dev_found("DELL0501"); init_done = true; } if (native) @@ -938,6 +948,9 @@ if (apple_gmux_present) return acpi_backlight_apple_gmux; + if (dell_uart_backlight_present) + return acpi_backlight_vendor; + /* Use ACPI video if available, except when native should be preferred. */ if ((video_caps & ACPI_VIDEO_BACKLIGHT) && !(native_available && prefer_native_over_acpi_video())) --- linux-xilinx-6.8.0.orig/drivers/acpi/x86/s2idle.c +++ linux-xilinx-6.8.0/drivers/acpi/x86/s2idle.c @@ -488,7 +488,19 @@ rev_id = 1; lps0_dsm_func_mask = validate_dsm(adev->handle, ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid); - lps0_dsm_func_mask_microsoft = -EINVAL; + if (lps0_dsm_func_mask > 0 && lps0_dsm_func_mask_microsoft > 0) { + unsigned int func_mask; + + /* + * Log a message if the _DSM function sets for two + * different UUIDs overlap. + */ + func_mask = lps0_dsm_func_mask & lps0_dsm_func_mask_microsoft; + if (func_mask) + acpi_handle_info(adev->handle, + "Duplicate LPS0 _DSM functions (mask: 0x%x)\n", + func_mask); + } } if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0) @@ -549,19 +561,22 @@ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); /* LPS0 entry */ - if (lps0_dsm_func_mask > 0) - acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ? - ACPI_LPS0_ENTRY_AMD : - ACPI_LPS0_ENTRY, + if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd()) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD, lps0_dsm_func_mask, lps0_dsm_guid); + if (lps0_dsm_func_mask_microsoft > 0) { - /* modern standby entry */ + /* Modern Standby entry */ acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); } + if (lps0_dsm_func_mask > 0 && !acpi_s2idle_vendor_amd()) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, + lps0_dsm_func_mask, lps0_dsm_guid); + list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) { if (handler->prepare) handler->prepare(); @@ -600,14 +615,14 @@ ACPI_LPS0_EXIT_AMD : ACPI_LPS0_EXIT, lps0_dsm_func_mask, lps0_dsm_guid); - if (lps0_dsm_func_mask_microsoft > 0) + + if (lps0_dsm_func_mask_microsoft > 0) { acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); - - /* Modern standby exit */ - if (lps0_dsm_func_mask_microsoft > 0) + /* Modern Standby exit */ acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); + } /* Screen on */ if (lps0_dsm_func_mask_microsoft > 0) --- linux-xilinx-6.8.0.orig/drivers/acpi/x86/utils.c +++ linux-xilinx-6.8.0/drivers/acpi/x86/utils.c @@ -197,16 +197,16 @@ } /* - * AMD systems from Renoir and Lucienne *require* that the NVME controller + * AMD systems from Renoir onwards *require* that the NVME controller * is put into D3 over a Modern Standby / suspend-to-idle cycle. * * This is "typically" accomplished using the `StorageD3Enable` * property in the _DSD that is checked via the `acpi_storage_d3` function - * but this property was introduced after many of these systems launched - * and most OEM systems don't have it in their BIOS. + * but some OEM systems still don't have it in their BIOS. * * The Microsoft documentation for StorageD3Enable mentioned that Windows has - * a hardcoded allowlist for D3 support, which was used for these platforms. + * a hardcoded allowlist for D3 support as well as a registry key to override + * the BIOS, which has been used for these cases. * * This allows quirking on Linux in a similar fashion. * @@ -219,19 +219,15 @@ * https://bugzilla.kernel.org/show_bug.cgi?id=216773 * https://bugzilla.kernel.org/show_bug.cgi?id=217003 * 2) On at least one HP system StorageD3Enable is missing on the second NVME - disk in the system. + * disk in the system. + * 3) On at least one HP Rembrandt system StorageD3Enable is missing on the only + * NVME device. */ -static const struct x86_cpu_id storage_d3_cpu_ids[] = { - X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 24, NULL), /* Picasso */ - X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */ - X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */ - X86_MATCH_VENDOR_FAM_MODEL(AMD, 25, 80, NULL), /* Cezanne */ - {} -}; - bool force_storage_d3(void) { - return x86_match_cpu(storage_d3_cpu_ids); + if (!cpu_feature_enabled(X86_FEATURE_ZEN)) + return false; + return acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0; } /* @@ -260,9 +256,10 @@ #define ACPI_QUIRK_SKIP_I2C_CLIENTS BIT(0) #define ACPI_QUIRK_UART1_SKIP BIT(1) #define ACPI_QUIRK_UART1_TTY_UART2_SKIP BIT(2) -#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(3) -#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(4) -#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS BIT(5) +#define ACPI_QUIRK_PNP_UART1_SKIP BIT(3) +#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY BIT(4) +#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY BIT(5) +#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS BIT(6) static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { /* @@ -342,6 +339,7 @@ DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), }, .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_PNP_UART1_SKIP | ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), }, { @@ -428,7 +426,7 @@ } EXPORT_SYMBOL_GPL(acpi_quirk_skip_i2c_client_enumeration); -int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip) +static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bool *skip) { struct acpi_device *adev = ACPI_COMPANION(controller_parent); const struct dmi_system_id *dmi_id; @@ -436,20 +434,22 @@ u64 uid; int ret; - *skip = false; - ret = acpi_dev_uid_to_integer(adev, &uid); if (ret) return 0; - /* to not match on PNP enumerated debug UARTs */ - if (!dev_is_platform(controller_parent)) - return 0; - dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids); if (dmi_id) quirks = (unsigned long)dmi_id->driver_data; + if (!dev_is_platform(controller_parent)) { + /* PNP enumerated UARTs */ + if ((quirks & ACPI_QUIRK_PNP_UART1_SKIP) && uid == 1) + *skip = true; + + return 0; + } + if ((quirks & ACPI_QUIRK_UART1_SKIP) && uid == 1) *skip = true; @@ -463,7 +463,6 @@ return 0; } -EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration); bool acpi_quirk_skip_gpio_event_handlers(void) { @@ -478,8 +477,41 @@ return (quirks & ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS); } EXPORT_SYMBOL_GPL(acpi_quirk_skip_gpio_event_handlers); +#else +static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bool *skip) +{ + return 0; +} #endif +int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip) +{ + struct acpi_device *adev = ACPI_COMPANION(controller_parent); + + *skip = false; + + /* + * The DELL0501 ACPI HID represents an UART (CID is set to PNP0501) with + * a backlight-controller attached. There is no separate ACPI device with + * an UartSerialBusV2() resource to model the backlight-controller. + * Set skip to true so that the tty core creates a serdev ctrl device. + * The backlight driver will manually create the serdev client device. + */ + if (acpi_dev_hid_match(adev, "DELL0501")) { + *skip = true; + /* + * Create a platform dev for dell-uart-backlight to bind to. + * This is a static device, so no need to store the result. + */ + platform_device_register_simple("dell-uart-backlight", PLATFORM_DEVID_NONE, + NULL, 0); + return 0; + } + + return acpi_dmi_skip_serdev_enumeration(controller_parent, skip); +} +EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration); + /* Lists of PMIC ACPI HIDs with an (often better) native charger driver */ static const struct { const char *hid; --- linux-xilinx-6.8.0.orig/drivers/android/Kconfig +++ linux-xilinx-6.8.0/drivers/android/Kconfig @@ -2,7 +2,7 @@ menu "Android" config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" + tristate "Android Binder IPC Driver" depends on MMU default n help @@ -14,8 +14,8 @@ between said processes. config ANDROID_BINDERFS - bool "Android Binderfs filesystem" - depends on ANDROID_BINDER_IPC + tristate "Android Binderfs filesystem" + depends on (ANDROID_BINDER_IPC=y) || (ANDROID_BINDER_IPC=m && m) default n help Binderfs is a pseudo-filesystem for the Android Binder IPC driver --- linux-xilinx-6.8.0.orig/drivers/android/Makefile +++ linux-xilinx-6.8.0/drivers/android/Makefile @@ -1,6 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only ccflags-y += -I$(src) # needed for trace events -obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o -obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +binder_linux-y := binder.o binder_alloc.o +obj-$(CONFIG_ANDROID_BINDER_IPC) += binder_linux.o +binder_linux-$(CONFIG_ANDROID_BINDERFS) += binderfs.o +binder_linux-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o + +# binder-$(CONFIG_ANDROID_BINDER_IPC) := binder.o binder_alloc.o +# binder-$(CONFIG_ANDROID_BINDERFS) += binderfs.o --- linux-xilinx-6.8.0.orig/drivers/android/binder.c +++ linux-xilinx-6.8.0/drivers/android/binder.c @@ -1708,8 +1708,10 @@ size_t object_size = 0; read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); - if (offset > buffer->data_size || read_size < sizeof(*hdr)) + if (offset > buffer->data_size || read_size < sizeof(*hdr) || + !IS_ALIGNED(offset, sizeof(u32))) return 0; + if (u) { if (copy_from_user(object, u + offset, read_size)) return 0; @@ -2930,8 +2932,7 @@ struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); ktime_t t_start_time = ktime_get(); - char *secctx = NULL; - u32 secctx_sz = 0; + struct lsmcontext lsmctx; struct list_head sgc_head; struct list_head pf_head; const void __user *user_buffer = (const void __user *) @@ -3210,8 +3211,8 @@ size_t added_size; security_cred_getsecid(proc->cred, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); - if (ret) { + ret = security_secid_to_secctx(secid, &lsmctx); + if (ret < 0) { binder_txn_error("%d:%d failed to get security context\n", thread->pid, proc->pid); return_error = BR_FAILED_REPLY; @@ -3219,7 +3220,7 @@ return_error_line = __LINE__; goto err_get_secctx_failed; } - added_size = ALIGN(secctx_sz, sizeof(u64)); + added_size = ALIGN(lsmctx.len, sizeof(u64)); extra_buffers_size += added_size; if (extra_buffers_size < added_size) { binder_txn_error("%d:%d integer overflow of extra_buffers_size\n", @@ -3253,23 +3254,23 @@ t->buffer = NULL; goto err_binder_alloc_buf_failed; } - if (secctx) { + if (lsmctx.context) { int err; size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + ALIGN(tr->offsets_size, sizeof(void *)) + ALIGN(extra_buffers_size, sizeof(void *)) - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); t->security_ctx = t->buffer->user_data + buf_offset; err = binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, - secctx, secctx_sz); + lsmctx.context, lsmctx.len); if (err) { t->security_ctx = 0; WARN_ON(1); } - security_release_secctx(secctx, secctx_sz); - secctx = NULL; + security_release_secctx(&lsmctx); + lsmctx.context = NULL; } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3313,7 +3314,7 @@ off_end_offset = off_start_offset + tr->offsets_size; sg_buf_offset = ALIGN(off_end_offset, sizeof(void *)); sg_buf_end_offset = sg_buf_offset + extra_buffers_size - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); off_min = 0; for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) { @@ -3691,8 +3692,8 @@ binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - if (secctx) - security_release_secctx(secctx, secctx_sz); + if (lsmctx.context) + security_release_secctx(&lsmctx); err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); @@ -5365,7 +5366,7 @@ goto err; break; case BINDER_SET_MAX_THREADS: { - int max_threads; + u32 max_threads; if (copy_from_user(&max_threads, ubuf, sizeof(max_threads))) { @@ -6631,9 +6632,20 @@ return ret; } -device_initcall(binder_init); +module_init(binder_init); +/* + * binder will have no exit function since binderfs instances can be mounted + * multiple times and also in user namespaces finding and destroying them all + * is not feasible without introducing insane locking. Just ignoring existing + * instances on module unload also wouldn't work since we would loose track of + * what major numer was dynamically allocated and also what minor numbers are + * already given out. So this would get us into all kinds of issues with device + * number reuse. So simply don't allow unloading unless we are forced to do so. + */ + +MODULE_AUTHOR("Google, Inc."); +MODULE_DESCRIPTION("Driver for Android binder device"); +MODULE_LICENSE("GPL v2"); #define CREATE_TRACE_POINTS #include "binder_trace.h" - -MODULE_LICENSE("GPL v2"); --- linux-xilinx-6.8.0.orig/drivers/android/binder_alloc.c +++ linux-xilinx-6.8.0/drivers/android/binder_alloc.c @@ -38,8 +38,7 @@ }; static uint32_t binder_alloc_debug_mask = BINDER_DEBUG_USER_ERROR; -module_param_named(debug_mask, binder_alloc_debug_mask, - uint, 0644); +module_param_named(alloc_debug_mask, binder_alloc_debug_mask, uint, 0644); #define binder_alloc_debug(mask, x...) \ do { \ --- linux-xilinx-6.8.0.orig/drivers/android/binder_alloc.h +++ linux-xilinx-6.8.0/drivers/android/binder_alloc.h @@ -6,6 +6,7 @@ #ifndef _LINUX_BINDER_ALLOC_H #define _LINUX_BINDER_ALLOC_H +#include #include #include #include @@ -111,7 +112,7 @@ bool oneway_spam_detected; }; -#ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST +#if IS_ENABLED(CONFIG_ANDROID_BINDER_IPC_SELFTEST) void binder_selftest_alloc(struct binder_alloc *alloc); #else static inline void binder_selftest_alloc(struct binder_alloc *alloc) {} --- linux-xilinx-6.8.0.orig/drivers/android/binder_internal.h +++ linux-xilinx-6.8.0/drivers/android/binder_internal.h @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -77,7 +78,7 @@ extern char *binder_devices_param; -#ifdef CONFIG_ANDROID_BINDERFS +#if IS_ENABLED(CONFIG_ANDROID_BINDERFS) extern bool is_binderfs_device(const struct inode *inode); extern struct dentry *binderfs_create_file(struct dentry *dir, const char *name, const struct file_operations *fops, @@ -98,7 +99,7 @@ static inline void binderfs_remove_file(struct dentry *dentry) {} #endif -#ifdef CONFIG_ANDROID_BINDERFS +#if IS_ENABLED(CONFIG_ANDROID_BINDERFS) extern int __init init_binderfs(void); #else static inline int __init init_binderfs(void) @@ -421,7 +422,7 @@ struct list_head todo; struct binder_stats stats; struct list_head delivered_death; - int max_threads; + u32 max_threads; int requested_threads; int requested_threads_started; int tmp_ref; --- linux-xilinx-6.8.0.orig/drivers/android/binderfs.c +++ linux-xilinx-6.8.0/drivers/android/binderfs.c @@ -120,7 +120,7 @@ struct super_block *sb = ref_inode->i_sb; struct binderfs_info *info = sb->s_fs_info; #if defined(CONFIG_IPC_NS) - bool use_reserve = (info->ipc_ns == &init_ipc_ns); + bool use_reserve = (info->ipc_ns == show_init_ipc_ns()); #else bool use_reserve = true; #endif @@ -397,7 +397,7 @@ struct dentry *root = sb->s_root; struct binderfs_info *info = sb->s_fs_info; #if defined(CONFIG_IPC_NS) - bool use_reserve = (info->ipc_ns == &init_ipc_ns); + bool use_reserve = (info->ipc_ns == show_init_ipc_ns()); #else bool use_reserve = true; #endif @@ -683,7 +683,7 @@ return -ENOMEM; info = sb->s_fs_info; - info->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns); + info->ipc_ns = get_ipc_ns_exported(current->nsproxy->ipc_ns); info->root_gid = make_kgid(sb->s_user_ns, 0); if (!gid_valid(info->root_gid)) --- linux-xilinx-6.8.0.orig/drivers/ata/ahci.c +++ linux-xilinx-6.8.0/drivers/ata/ahci.c @@ -431,7 +431,6 @@ { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */ /* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */ { PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */ - { PCI_VDEVICE(INTEL, 0x7ae2), board_ahci_low_power }, /* Alder Lake-P AHCI */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -671,19 +670,6 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, struct ahci_host_priv *hpriv) { - if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) { - switch (pdev->device) { - case 0x1166: - dev_info(&pdev->dev, "ASM1166 has only six ports\n"); - hpriv->saved_port_map = 0x3f; - break; - case 0x1064: - dev_info(&pdev->dev, "ASM1064 has only four ports\n"); - hpriv->saved_port_map = 0xf; - break; - } - } - if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { dev_info(&pdev->dev, "JMB361 has only one port\n"); hpriv->saved_port_map = 1; @@ -1660,6 +1646,14 @@ if (!(hpriv->flags & AHCI_HFLAG_USE_LPM_POLICY)) return; + /* If no LPM states are supported by the HBA, do not bother with LPM */ + if ((ap->host->flags & ATA_HOST_NO_PART) && + (ap->host->flags & ATA_HOST_NO_SSC) && + (ap->host->flags & ATA_HOST_NO_DEVSLP)) { + ata_port_dbg(ap, "no LPM states supported, not enabling LPM\n"); + return; + } + /* user modified policy via module param */ if (mobile_lpm_policy != -1) { policy = mobile_lpm_policy; @@ -1904,8 +1898,10 @@ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); - if (!host) - return -ENOMEM; + if (!host) { + rc = -ENOMEM; + goto err_rm_sysfs_file; + } host->private_data = hpriv; if (ahci_init_msi(pdev, n_ports, hpriv) < 0) { @@ -1958,11 +1954,11 @@ /* initialize adapter */ rc = ahci_configure_dma_masks(pdev, hpriv); if (rc) - return rc; + goto err_rm_sysfs_file; rc = ahci_pci_reset_controller(host); if (rc) - return rc; + goto err_rm_sysfs_file; ahci_pci_init_controller(host); ahci_pci_print_info(host); @@ -1971,10 +1967,15 @@ rc = ahci_host_activate(host, &ahci_sht); if (rc) - return rc; + goto err_rm_sysfs_file; pm_runtime_put_noidle(&pdev->dev); return 0; + +err_rm_sysfs_file: + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_remapped_nvme.attr, NULL); + return rc; } static void ahci_shutdown_one(struct pci_dev *pdev) --- linux-xilinx-6.8.0.orig/drivers/ata/libata-core.c +++ linux-xilinx-6.8.0/drivers/ata/libata-core.c @@ -2539,7 +2539,7 @@ bool cdl_enabled; u64 val; - if (ata_id_major_version(dev->id) < 12) + if (ata_id_major_version(dev->id) < 11) goto not_supported; if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE) || @@ -4180,8 +4180,8 @@ { "PIONEER BD-RW BDR-207M", NULL, ATA_HORKAGE_NOLPM }, { "PIONEER BD-RW BDR-205", NULL, ATA_HORKAGE_NOLPM }, - /* Crucial BX100 SSD 500GB has broken LPM support */ - { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, + /* Crucial devices with broken LPM support */ + { "CT*0BX*00SSD1", NULL, ATA_HORKAGE_NOLPM }, /* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */ { "Crucial_CT512MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | @@ -4199,6 +4199,12 @@ ATA_HORKAGE_ZERO_AFTER_TRIM | ATA_HORKAGE_NOLPM }, + /* Apacer models with LPM issues */ + { "Apacer AS340*", NULL, ATA_HORKAGE_NOLPM }, + + /* AMD Radeon devices with broken LPM support */ + { "R3SL240G", NULL, ATA_HORKAGE_NOLPM }, + /* These specific Samsung models/firmware-revs do not handle LPM well */ { "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM }, { "SAMSUNG SSD PM830 mSATA *", "CXM13D1Q", ATA_HORKAGE_NOLPM }, @@ -5527,6 +5533,18 @@ return ap; } +void ata_port_free(struct ata_port *ap) +{ + if (!ap) + return; + + kfree(ap->pmp_link); + kfree(ap->slave_link); + kfree(ap->ncq_sense_buf); + kfree(ap); +} +EXPORT_SYMBOL_GPL(ata_port_free); + static void ata_devres_release(struct device *gendev, void *res) { struct ata_host *host = dev_get_drvdata(gendev); @@ -5553,12 +5571,7 @@ int i; for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap = host->ports[i]; - - kfree(ap->pmp_link); - kfree(ap->slave_link); - kfree(ap->ncq_sense_buf); - kfree(ap); + ata_port_free(host->ports[i]); host->ports[i] = NULL; } kfree(host); @@ -5608,8 +5621,10 @@ if (!host) return NULL; - if (!devres_open_group(dev, NULL, GFP_KERNEL)) - goto err_free; + if (!devres_open_group(dev, NULL, GFP_KERNEL)) { + kfree(host); + return NULL; + } dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); if (!dr) @@ -5641,8 +5656,6 @@ err_out: devres_release_group(dev, NULL); - err_free: - kfree(host); return NULL; } EXPORT_SYMBOL_GPL(ata_host_alloc); @@ -5941,7 +5954,7 @@ * allocation time. */ for (i = host->n_ports; host->ports[i]; i++) - kfree(host->ports[i]); + ata_port_free(host->ports[i]); /* give ports names and add SCSI hosts */ for (i = 0; i < host->n_ports; i++) { --- linux-xilinx-6.8.0.orig/drivers/ata/libata-eh.c +++ linux-xilinx-6.8.0/drivers/ata/libata-eh.c @@ -712,8 +712,10 @@ ehc->saved_ncq_enabled |= 1 << devno; /* If we are resuming, wake up the device */ - if (ap->pflags & ATA_PFLAG_RESUMING) + if (ap->pflags & ATA_PFLAG_RESUMING) { + dev->flags |= ATA_DFLAG_RESUMING; ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE; + } } } @@ -3169,6 +3171,7 @@ return 0; err: + dev->flags &= ~ATA_DFLAG_RESUMING; *r_failed_dev = dev; return rc; } --- linux-xilinx-6.8.0.orig/drivers/ata/libata-scsi.c +++ linux-xilinx-6.8.0/drivers/ata/libata-scsi.c @@ -1828,11 +1828,11 @@ 2 }; - /* set scsi removable (RMB) bit per ata bit, or if the - * AHCI port says it's external (Hotplug-capable, eSATA). + /* + * Set the SCSI Removable Media Bit (RMB) if the ATA removable media + * device bit (obsolete since ATA-8 ACS) is set. */ - if (ata_id_removable(args->id) || - (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL)) + if (ata_id_removable(args->id)) hdr[1] |= (1 << 7); if (args->dev->class == ATA_DEV_ZAC) { @@ -4730,6 +4730,7 @@ struct ata_link *link; struct ata_device *dev; unsigned long flags; + bool do_resume; int ret = 0; mutex_lock(&ap->scsi_scan_mutex); @@ -4744,25 +4745,34 @@ * bail out. */ if (ap->pflags & ATA_PFLAG_SUSPENDED) - goto unlock; + goto unlock_ap; if (!sdev) continue; if (scsi_device_get(sdev)) continue; + do_resume = dev->flags & ATA_DFLAG_RESUMING; + spin_unlock_irqrestore(ap->lock, flags); + if (do_resume) { + ret = scsi_resume_device(sdev); + if (ret == -EWOULDBLOCK) + goto unlock_scan; + dev->flags &= ~ATA_DFLAG_RESUMING; + } ret = scsi_rescan_device(sdev); scsi_device_put(sdev); spin_lock_irqsave(ap->lock, flags); if (ret) - goto unlock; + goto unlock_ap; } } -unlock: +unlock_ap: spin_unlock_irqrestore(ap->lock, flags); +unlock_scan: mutex_unlock(&ap->scsi_scan_mutex); /* Reschedule with a delay if scsi_rescan_device() returned an error */ --- linux-xilinx-6.8.0.orig/drivers/ata/pata_legacy.c +++ linux-xilinx-6.8.0/drivers/ata/pata_legacy.c @@ -173,8 +173,6 @@ static struct legacy_probe probe_list[NR_HOST]; static struct legacy_data legacy_data[NR_HOST]; static struct ata_host *legacy_host[NR_HOST]; -static int nr_legacy_host; - /** * legacy_probe_add - Add interface to probe list @@ -1276,9 +1274,11 @@ { int i; - for (i = 0; i < nr_legacy_host; i++) { + for (i = 0; i < NR_HOST; i++) { struct legacy_data *ld = &legacy_data[i]; - ata_host_detach(legacy_host[i]); + + if (legacy_host[i]) + ata_host_detach(legacy_host[i]); platform_device_unregister(ld->platform_dev); } } --- linux-xilinx-6.8.0.orig/drivers/ata/sata_gemini.c +++ linux-xilinx-6.8.0/drivers/ata/sata_gemini.c @@ -200,7 +200,10 @@ pclk = sg->sata0_pclk; else pclk = sg->sata1_pclk; - clk_enable(pclk); + ret = clk_enable(pclk); + if (ret) + return ret; + msleep(10); /* Do not keep clocking a bridge that is not online */ --- linux-xilinx-6.8.0.orig/drivers/ata/sata_mv.c +++ linux-xilinx-6.8.0/drivers/ata/sata_mv.c @@ -787,37 +787,6 @@ }, }; -static const struct pci_device_id mv_pci_tbl[] = { - { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, - { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, - { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, - { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, - /* RocketRAID 1720/174x have different identifiers */ - { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, - - { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, - { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, - { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, - { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, - { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, - - { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, - - /* Adaptec 1430SA */ - { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, - - /* Marvell 7042 support */ - { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 }, - - /* Highpoint RocketRAID PCIe series */ - { PCI_VDEVICE(TTI, 0x2300), chip_7042 }, - { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, - - { } /* terminate list */ -}; - static const struct mv_hw_ops mv5xxx_ops = { .phy_errata = mv5_phy_errata, .enable_leds = mv5_enable_leds, @@ -4303,6 +4272,36 @@ static int mv_pci_device_resume(struct pci_dev *pdev); #endif +static const struct pci_device_id mv_pci_tbl[] = { + { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, + { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, + { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, + { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1720/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, + + { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, + { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, + { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, + + { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, + + /* Adaptec 1430SA */ + { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, + + /* Marvell 7042 support */ + { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 }, + + /* Highpoint RocketRAID PCIe series */ + { PCI_VDEVICE(TTI, 0x2300), chip_7042 }, + { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, + + { } /* terminate list */ +}; static struct pci_driver mv_pci_driver = { .name = DRV_NAME, @@ -4315,6 +4314,7 @@ #endif }; +MODULE_DEVICE_TABLE(pci, mv_pci_tbl); /** * mv_print_info - Dump key info to kernel log for perusal. @@ -4487,7 +4487,6 @@ MODULE_AUTHOR("Brett Russ"); MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers"); MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(pci, mv_pci_tbl); MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:" DRV_NAME); --- linux-xilinx-6.8.0.orig/drivers/ata/sata_sx4.c +++ linux-xilinx-6.8.0/drivers/ata/sata_sx4.c @@ -957,8 +957,7 @@ offset -= (idx * window_size); idx++; - dist = ((long) (window_size - (offset + size))) >= 0 ? size : - (long) (window_size - offset); + dist = min(size, window_size - offset); memcpy_fromio(psource, dimm_mmio + offset / 4, dist); psource += dist; @@ -1005,8 +1004,7 @@ readl(mmio + PDC_DIMM_WINDOW_CTLR); offset -= (idx * window_size); idx++; - dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size : - (long) (window_size - offset); + dist = min(size, window_size - offset); memcpy_toio(dimm_mmio + offset / 4, psource, dist); writel(0x01, mmio + PDC_GENERAL_CTLR); readl(mmio + PDC_GENERAL_CTLR); --- linux-xilinx-6.8.0.orig/drivers/base/base.h +++ linux-xilinx-6.8.0/drivers/base/base.h @@ -192,11 +192,14 @@ void devices_kset_move_last(struct device *dev); #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) -void module_add_driver(struct module *mod, struct device_driver *drv); +int module_add_driver(struct module *mod, struct device_driver *drv); void module_remove_driver(struct device_driver *drv); #else -static inline void module_add_driver(struct module *mod, - struct device_driver *drv) { } +static inline int module_add_driver(struct module *mod, + struct device_driver *drv) +{ + return 0; +} static inline void module_remove_driver(struct device_driver *drv) { } #endif --- linux-xilinx-6.8.0.orig/drivers/base/bus.c +++ linux-xilinx-6.8.0/drivers/base/bus.c @@ -674,7 +674,12 @@ if (error) goto out_del_list; } - module_add_driver(drv->owner, drv); + error = module_add_driver(drv->owner, drv); + if (error) { + printk(KERN_ERR "%s: failed to create module links for %s\n", + __func__, drv->name); + goto out_detach; + } error = driver_create_file(drv, &driver_attr_uevent); if (error) { @@ -699,6 +704,8 @@ return 0; +out_detach: + driver_detach(drv); out_del_list: klist_del(&priv->knode_bus); out_unregister: --- linux-xilinx-6.8.0.orig/drivers/base/cacheinfo.c +++ linux-xilinx-6.8.0/drivers/base/cacheinfo.c @@ -61,6 +61,9 @@ if (!cache_leaves(cpu)) return false; + if (!per_cpu_cacheinfo(cpu)) + return false; + llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1); return (llc->attributes & CACHE_ID) || !!llc->fw_token; @@ -554,7 +557,11 @@ */ ci_cacheinfo(cpu)->early_ci_levels = false; - if (cache_leaves(cpu) <= early_leaves) + /* + * Some architectures (e.g., x86) do not use early initialization. + * Allocate memory now in such case. + */ + if (cache_leaves(cpu) <= early_leaves && per_cpu_cacheinfo(cpu)) return 0; kfree(per_cpu_cacheinfo(cpu)); --- linux-xilinx-6.8.0.orig/drivers/base/core.c +++ linux-xilinx-6.8.0/drivers/base/core.c @@ -44,6 +44,7 @@ static void __fw_devlink_link_to_consumers(struct device *dev); static bool fw_devlink_drv_reg_done; static bool fw_devlink_best_effort; +static struct workqueue_struct *device_link_wq; /** * __fwnode_link_add - Create a link between two fwnode_handles. @@ -532,12 +533,26 @@ /* * It may take a while to complete this work because of the SRCU * synchronization in device_link_release_fn() and if the consumer or - * supplier devices get deleted when it runs, so put it into the "long" - * workqueue. + * supplier devices get deleted when it runs, so put it into the + * dedicated workqueue. */ - queue_work(system_long_wq, &link->rm_work); + queue_work(device_link_wq, &link->rm_work); } +/** + * device_link_wait_removal - Wait for ongoing devlink removal jobs to terminate + */ +void device_link_wait_removal(void) +{ + /* + * devlink removal jobs are queued in the dedicated work queue. + * To be sure that all removal jobs are terminated, ensure that any + * scheduled work has run to completion. + */ + flush_workqueue(device_link_wq); +} +EXPORT_SYMBOL_GPL(device_link_wait_removal); + static struct class devlink_class = { .name = "devlink", .dev_groups = devlink_groups, @@ -2657,8 +2672,11 @@ if (!env) return -ENOMEM; + /* Synchronize with really_probe() */ + device_lock(dev); /* let the kset specific function add its keys */ retval = kset->uevent_ops->uevent(&dev->kobj, env); + device_unlock(dev); if (retval) goto out; @@ -4098,9 +4116,14 @@ sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj); if (!sysfs_dev_char_kobj) goto char_kobj_err; + device_link_wq = alloc_workqueue("device_link_wq", 0, 0); + if (!device_link_wq) + goto wq_err; return 0; + wq_err: + kobject_put(sysfs_dev_char_kobj); char_kobj_err: kobject_put(sysfs_dev_block_kobj); block_kobj_err: --- linux-xilinx-6.8.0.orig/drivers/base/cpu.c +++ linux-xilinx-6.8.0/drivers/base/cpu.c @@ -588,6 +588,7 @@ CPU_SHOW_VULN_FALLBACK(retbleed); CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow); CPU_SHOW_VULN_FALLBACK(gds); +CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling); static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); @@ -602,6 +603,7 @@ static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL); static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL); static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); +static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL); static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr, @@ -617,6 +619,7 @@ &dev_attr_retbleed.attr, &dev_attr_spec_rstack_overflow.attr, &dev_attr_gather_data_sampling.attr, + &dev_attr_reg_file_data_sampling.attr, NULL }; --- linux-xilinx-6.8.0.orig/drivers/base/memory.c +++ linux-xilinx-6.8.0/drivers/base/memory.c @@ -188,6 +188,7 @@ unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; unsigned long nr_vmemmap_pages = 0; + struct memory_notify arg; struct zone *zone; int ret; @@ -207,9 +208,19 @@ if (mem->altmap) nr_vmemmap_pages = mem->altmap->free; + arg.altmap_start_pfn = start_pfn; + arg.altmap_nr_pages = nr_vmemmap_pages; + arg.start_pfn = start_pfn + nr_vmemmap_pages; + arg.nr_pages = nr_pages - nr_vmemmap_pages; mem_hotplug_begin(); + ret = memory_notify(MEM_PREPARE_ONLINE, &arg); + ret = notifier_to_errno(ret); + if (ret) + goto out_notifier; + if (nr_vmemmap_pages) { - ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, zone); + ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, + zone, mem->altmap->inaccessible); if (ret) goto out; } @@ -231,7 +242,11 @@ nr_vmemmap_pages); mem->zone = zone; + mem_hotplug_done(); + return ret; out: + memory_notify(MEM_FINISH_OFFLINE, &arg); +out_notifier: mem_hotplug_done(); return ret; } @@ -244,6 +259,7 @@ unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; unsigned long nr_vmemmap_pages = 0; + struct memory_notify arg; int ret; if (!mem->zone) @@ -275,6 +291,11 @@ mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages); mem->zone = NULL; + arg.altmap_start_pfn = start_pfn; + arg.altmap_nr_pages = nr_vmemmap_pages; + arg.start_pfn = start_pfn + nr_vmemmap_pages; + arg.nr_pages = nr_pages - nr_vmemmap_pages; + memory_notify(MEM_FINISH_OFFLINE, &arg); out: mem_hotplug_done(); return ret; --- linux-xilinx-6.8.0.orig/drivers/base/module.c +++ linux-xilinx-6.8.0/drivers/base/module.c @@ -30,14 +30,14 @@ mutex_unlock(&drivers_dir_mutex); } -void module_add_driver(struct module *mod, struct device_driver *drv) +int module_add_driver(struct module *mod, struct device_driver *drv) { char *driver_name; - int no_warn; struct module_kobject *mk = NULL; + int ret; if (!drv) - return; + return 0; if (mod) mk = &mod->mkobj; @@ -56,17 +56,37 @@ } if (!mk) - return; + return 0; + + ret = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module"); + if (ret) + return ret; - /* Don't check return codes; these calls are idempotent */ - no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module"); driver_name = make_driver_name(drv); - if (driver_name) { - module_create_drivers_dir(mk); - no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, - driver_name); - kfree(driver_name); + if (!driver_name) { + ret = -ENOMEM; + goto out; + } + + module_create_drivers_dir(mk); + if (!mk->drivers_dir) { + ret = -EINVAL; + goto out; } + + ret = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, driver_name); + if (ret) + goto out; + + kfree(driver_name); + + return 0; +out: + sysfs_remove_link(&drv->p->kobj, "module"); + sysfs_remove_link(mk->drivers_dir, driver_name); + kfree(driver_name); + + return ret; } void module_remove_driver(struct device_driver *drv) --- linux-xilinx-6.8.0.orig/drivers/base/node.c +++ linux-xilinx-6.8.0/drivers/base/node.c @@ -126,7 +126,7 @@ } static struct node_access_nodes *node_init_node_access(struct node *node, - unsigned int access) + enum access_coordinate_class access) { struct node_access_nodes *access_node; struct device *dev; @@ -191,7 +191,7 @@ * @access: The access class the for the given attributes */ void node_set_perf_attrs(unsigned int nid, struct access_coordinate *coord, - unsigned int access) + enum access_coordinate_class access) { struct node_access_nodes *c; struct node *node; @@ -689,7 +689,7 @@ */ int register_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, - unsigned int access) + enum access_coordinate_class access) { struct node *init_node, *targ_node; struct node_access_nodes *initiator, *target; --- linux-xilinx-6.8.0.orig/drivers/base/power/wakeirq.c +++ linux-xilinx-6.8.0/drivers/base/power/wakeirq.c @@ -313,8 +313,10 @@ return; if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && - wirq->status & WAKE_IRQ_DEDICATED_REVERSE) + wirq->status & WAKE_IRQ_DEDICATED_REVERSE) { enable_irq(wirq->irq); + wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; + } } /** --- linux-xilinx-6.8.0.orig/drivers/base/regmap/regcache-maple.c +++ linux-xilinx-6.8.0/drivers/base/regmap/regcache-maple.c @@ -112,7 +112,7 @@ unsigned long *entry, *lower, *upper; unsigned long lower_index, lower_last; unsigned long upper_index, upper_last; - int ret; + int ret = 0; lower = NULL; upper = NULL; @@ -145,7 +145,7 @@ upper_index = max + 1; upper_last = mas.last; - upper = kmemdup(&entry[max + 1], + upper = kmemdup(&entry[max - mas.index + 1], ((mas.last - max) * sizeof(unsigned long)), map->alloc_flags); @@ -244,7 +244,7 @@ unsigned long lmin = min; unsigned long lmax = max; unsigned int r, v, sync_start; - int ret; + int ret = 0; bool sync_needed = false; map->cache_bypass = true; --- linux-xilinx-6.8.0.orig/drivers/base/regmap/regmap-i2c.c +++ linux-xilinx-6.8.0/drivers/base/regmap/regmap-i2c.c @@ -350,7 +350,8 @@ if (quirks->max_write_len && (bus->max_raw_write == 0 || bus->max_raw_write > quirks->max_write_len)) - max_write = quirks->max_write_len; + max_write = quirks->max_write_len - + (config->reg_bits + config->pad_bits) / BITS_PER_BYTE; if (max_read || max_write) { ret_bus = kmemdup(bus, sizeof(*bus), GFP_KERNEL); --- linux-xilinx-6.8.0.orig/drivers/base/regmap/regmap.c +++ linux-xilinx-6.8.0/drivers/base/regmap/regmap.c @@ -2837,6 +2837,43 @@ EXPORT_SYMBOL_GPL(regmap_read); /** + * regmap_read_bypassed() - Read a value from a single register direct + * from the device, bypassing the cache + * + * @map: Register map to read from + * @reg: Register to be read from + * @val: Pointer to store read value + * + * A value of zero will be returned on success, a negative errno will + * be returned in error cases. + */ +int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val) +{ + int ret; + bool bypass, cache_only; + + if (!IS_ALIGNED(reg, map->reg_stride)) + return -EINVAL; + + map->lock(map->lock_arg); + + bypass = map->cache_bypass; + cache_only = map->cache_only; + map->cache_bypass = true; + map->cache_only = false; + + ret = _regmap_read(map, reg, val); + + map->cache_bypass = bypass; + map->cache_only = cache_only; + + map->unlock(map->lock_arg); + + return ret; +} +EXPORT_SYMBOL_GPL(regmap_read_bypassed); + +/** * regmap_raw_read() - Read raw data from the device * * @map: Register map to read from --- linux-xilinx-6.8.0.orig/drivers/block/aoe/aoecmd.c +++ linux-xilinx-6.8.0/drivers/block/aoe/aoecmd.c @@ -419,13 +419,16 @@ rcu_read_lock(); for_each_netdev_rcu(&init_net, ifp) { dev_hold(ifp); - if (!is_aoe_netif(ifp)) - goto cont; + if (!is_aoe_netif(ifp)) { + dev_put(ifp); + continue; + } skb = new_skb(sizeof *h + sizeof *ch); if (skb == NULL) { printk(KERN_INFO "aoe: skb alloc failure\n"); - goto cont; + dev_put(ifp); + continue; } skb_put(skb, sizeof *h + sizeof *ch); skb->dev = ifp; @@ -440,9 +443,6 @@ h->major = cpu_to_be16(aoemajor); h->minor = aoeminor; h->cmd = AOECMD_CFG; - -cont: - dev_put(ifp); } rcu_read_unlock(); } --- linux-xilinx-6.8.0.orig/drivers/block/aoe/aoenet.c +++ linux-xilinx-6.8.0/drivers/block/aoe/aoenet.c @@ -63,6 +63,7 @@ pr_warn("aoe: packet could not be sent on %s. %s\n", ifp ? ifp->name : "netif", "consider increasing tx_queue_len"); + dev_put(ifp); spin_lock_irq(&txlock); } return 0; --- linux-xilinx-6.8.0.orig/drivers/block/nbd.c +++ linux-xilinx-6.8.0/drivers/block/nbd.c @@ -567,7 +567,10 @@ return result == -ERESTARTSYS || result == -EINTR; } -/* always call with the tx_lock held */ +/* + * Returns BLK_STS_RESOURCE if the caller should retry after a delay. Returns + * -EAGAIN if the caller should requeue @cmd. Returns -EIO if sending failed. + */ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) { struct request *req = blk_mq_rq_from_pdu(cmd); @@ -584,6 +587,9 @@ u32 nbd_cmd_flags = 0; int sent = nsock->sent, skip = 0; + lockdep_assert_held(&cmd->lock); + lockdep_assert_held(&nsock->tx_lock); + iov_iter_kvec(&from, ITER_SOURCE, &iov, 1, sizeof(request)); type = req_to_nbd_cmd_type(req); @@ -648,7 +654,7 @@ nsock->sent = sent; } set_bit(NBD_CMD_REQUEUED, &cmd->flags); - return BLK_STS_RESOURCE; + return (__force int)BLK_STS_RESOURCE; } dev_err_ratelimited(disk_to_dev(nbd->disk), "Send control failed (result %d)\n", result); @@ -689,7 +695,7 @@ nsock->pending = req; nsock->sent = sent; set_bit(NBD_CMD_REQUEUED, &cmd->flags); - return BLK_STS_RESOURCE; + return (__force int)BLK_STS_RESOURCE; } dev_err(disk_to_dev(nbd->disk), "Send data failed (result %d)\n", @@ -986,7 +992,7 @@ return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags); } -static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) +static blk_status_t nbd_handle_cmd(struct nbd_cmd *cmd, int index) { struct request *req = blk_mq_rq_from_pdu(cmd); struct nbd_device *nbd = cmd->nbd; @@ -994,18 +1000,20 @@ struct nbd_sock *nsock; int ret; + lockdep_assert_held(&cmd->lock); + config = nbd_get_config_unlocked(nbd); if (!config) { dev_err_ratelimited(disk_to_dev(nbd->disk), "Socks array is empty\n"); - return -EINVAL; + return BLK_STS_IOERR; } if (index >= config->num_connections) { dev_err_ratelimited(disk_to_dev(nbd->disk), "Attempted send on invalid socket\n"); nbd_config_put(nbd); - return -EINVAL; + return BLK_STS_IOERR; } cmd->status = BLK_STS_OK; again: @@ -1028,7 +1036,7 @@ */ sock_shutdown(nbd); nbd_config_put(nbd); - return -EIO; + return BLK_STS_IOERR; } goto again; } @@ -1041,7 +1049,7 @@ blk_mq_start_request(req); if (unlikely(nsock->pending && nsock->pending != req)) { nbd_requeue_cmd(cmd); - ret = 0; + ret = BLK_STS_OK; goto out; } /* @@ -1060,19 +1068,19 @@ "Request send failed, requeueing\n"); nbd_mark_nsock_dead(nbd, nsock, 1); nbd_requeue_cmd(cmd); - ret = 0; + ret = BLK_STS_OK; } out: mutex_unlock(&nsock->tx_lock); nbd_config_put(nbd); - return ret; + return ret < 0 ? BLK_STS_IOERR : (__force blk_status_t)ret; } static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { struct nbd_cmd *cmd = blk_mq_rq_to_pdu(bd->rq); - int ret; + blk_status_t ret; /* * Since we look at the bio's to send the request over the network we @@ -1092,10 +1100,6 @@ * appropriate. */ ret = nbd_handle_cmd(cmd, hctx->queue_num); - if (ret < 0) - ret = BLK_STS_IOERR; - else if (!ret) - ret = BLK_STS_OK; mutex_unlock(&cmd->lock); return ret; @@ -2433,6 +2437,12 @@ } dev_list = nla_nest_start_noflag(reply, NBD_ATTR_DEVICE_LIST); + if (!dev_list) { + nlmsg_free(reply); + ret = -EMSGSIZE; + goto out; + } + if (index == -1) { ret = idr_for_each(&nbd_index_idr, &status_cb, reply); if (ret) { --- linux-xilinx-6.8.0.orig/drivers/block/null_blk/main.c +++ linux-xilinx-6.8.0/drivers/block/null_blk/main.c @@ -392,13 +392,25 @@ static int nullb_apply_submit_queues(struct nullb_device *dev, unsigned int submit_queues) { - return nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues); + int ret; + + mutex_lock(&lock); + ret = nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues); + mutex_unlock(&lock); + + return ret; } static int nullb_apply_poll_queues(struct nullb_device *dev, unsigned int poll_queues) { - return nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues); + int ret; + + mutex_lock(&lock); + ret = nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues); + mutex_unlock(&lock); + + return ret; } NULLB_DEVICE_ATTR(size, ulong, NULL); @@ -444,28 +456,32 @@ if (ret < 0) return ret; + ret = count; + mutex_lock(&lock); if (!dev->power && newp) { if (test_and_set_bit(NULLB_DEV_FL_UP, &dev->flags)) - return count; + goto out; + ret = null_add_dev(dev); if (ret) { clear_bit(NULLB_DEV_FL_UP, &dev->flags); - return ret; + goto out; } set_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags); dev->power = newp; + ret = count; } else if (dev->power && !newp) { if (test_and_clear_bit(NULLB_DEV_FL_UP, &dev->flags)) { - mutex_lock(&lock); dev->power = newp; null_del_dev(dev->nullb); - mutex_unlock(&lock); } clear_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags); } - return count; +out: + mutex_unlock(&lock); + return ret; } CONFIGFS_ATTR(nullb_device_, power); @@ -2033,8 +2049,8 @@ return -EINVAL; } - dev->blocksize = round_down(dev->blocksize, 512); - dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096); + if (blk_validate_block_size(dev->blocksize)) + return -EINVAL; if (dev->queue_mode == NULL_Q_MQ && dev->use_per_node_hctx) { if (dev->submit_queues != nr_online_nodes) @@ -2173,15 +2189,12 @@ nullb->q->queuedata = nullb; blk_queue_flag_set(QUEUE_FLAG_NONROT, nullb->q); - mutex_lock(&lock); rv = ida_alloc(&nullb_indexes, GFP_KERNEL); - if (rv < 0) { - mutex_unlock(&lock); + if (rv < 0) goto out_cleanup_zone; - } + nullb->index = rv; dev->index = rv; - mutex_unlock(&lock); blk_queue_logical_block_size(nullb->q, dev->blocksize); blk_queue_physical_block_size(nullb->q, dev->blocksize); @@ -2205,9 +2218,7 @@ if (rv) goto out_ida_free; - mutex_lock(&lock); list_add_tail(&nullb->list, &nullb_list); - mutex_unlock(&lock); pr_info("disk %s created\n", nullb->disk_name); @@ -2256,7 +2267,9 @@ if (!dev) return -ENOMEM; + mutex_lock(&lock); ret = null_add_dev(dev); + mutex_unlock(&lock); if (ret) { null_free_dev(dev); return ret; @@ -2372,10 +2385,13 @@ if (g_queue_mode == NULL_Q_MQ && shared_tags) blk_mq_free_tag_set(&tag_set); + + mutex_destroy(&lock); } module_init(null_init); module_exit(null_exit); MODULE_AUTHOR("Jens Axboe "); +MODULE_DESCRIPTION("multi queue aware block test driver"); MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/block/null_blk/zoned.c +++ linux-xilinx-6.8.0/drivers/block/null_blk/zoned.c @@ -83,6 +83,17 @@ return -EINVAL; } + /* + * If a smaller zone capacity was requested, do not allow a smaller last + * zone at the same time as such zone configuration does not correspond + * to any real zoned device. + */ + if (dev->zone_capacity != dev->zone_size && + dev->size & (dev->zone_size - 1)) { + pr_err("A smaller last zone is not allowed with zone capacity smaller than zone size.\n"); + return -EINVAL; + } + zone_capacity_sects = mb_to_sects(dev->zone_capacity); dev_capacity_sects = mb_to_sects(dev->size); dev->zone_size_sects = mb_to_sects(dev->zone_size); @@ -112,7 +123,7 @@ if (dev->zone_max_active && dev->zone_max_open > dev->zone_max_active) { dev->zone_max_open = dev->zone_max_active; pr_info("changed the maximum number of open zones to %u\n", - dev->nr_zones); + dev->zone_max_open); } else if (dev->zone_max_open >= dev->nr_zones - dev->zone_nr_conv) { dev->zone_max_open = 0; pr_info("zone_max_open limit disabled, limit >= zone count\n"); --- linux-xilinx-6.8.0.orig/drivers/block/rbd.c +++ linux-xilinx-6.8.0/drivers/block/rbd.c @@ -89,7 +89,7 @@ #define RBD_MINORS_PER_MAJOR 256 #define RBD_SINGLE_MAJOR_PART_SHIFT 4 -#define RBD_MAX_PARENT_CHAIN_LEN 16 +#define RBD_MAX_PARENT_CHAIN_LEN 128 #define RBD_SNAP_DEV_NAME_PREFIX "snap_" #define RBD_MAX_SNAP_NAME_LEN \ --- linux-xilinx-6.8.0.orig/drivers/bluetooth/ath3k.c +++ linux-xilinx-6.8.0/drivers/bluetooth/ath3k.c @@ -3,7 +3,6 @@ * Copyright (c) 2008-2009 Atheros Communications Inc. */ - #include #include #include @@ -128,7 +127,6 @@ * for AR3012 */ static const struct usb_device_id ath3k_blist_tbl[] = { - /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, @@ -202,7 +200,7 @@ #define TIMEGAP_USEC_MAX 100 static int ath3k_load_firmware(struct usb_device *udev, - const struct firmware *firmware) + const struct firmware *firmware) { u8 *send_buf; int len = 0; @@ -237,9 +235,9 @@ memcpy(send_buf, firmware->data + sent, size); err = usb_bulk_msg(udev, pipe, send_buf, size, - &len, 3000); + &len, 3000); - if (err || (len != size)) { + if (err || len != size) { ath3k_log_failed_loading(err, len, size, count); goto error; } @@ -262,7 +260,7 @@ } static int ath3k_get_version(struct usb_device *udev, - struct ath3k_version *version) + struct ath3k_version *version) { return usb_control_msg_recv(udev, 0, ATH3K_GETVERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, @@ -271,7 +269,7 @@ } static int ath3k_load_fwfile(struct usb_device *udev, - const struct firmware *firmware) + const struct firmware *firmware) { u8 *send_buf; int len = 0; @@ -310,8 +308,8 @@ memcpy(send_buf, firmware->data + sent, size); err = usb_bulk_msg(udev, pipe, send_buf, size, - &len, 3000); - if (err || (len != size)) { + &len, 3000); + if (err || len != size) { ath3k_log_failed_loading(err, len, size, count); kfree(send_buf); return err; @@ -425,7 +423,6 @@ } switch (fw_version.ref_clock) { - case ATH3K_XTAL_FREQ_26M: clk_value = 26; break; @@ -441,7 +438,7 @@ } snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", - le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); + le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); ret = request_firmware(&firmware, filename, &udev->dev); if (ret < 0) { @@ -456,7 +453,7 @@ } static int ath3k_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); @@ -505,10 +502,10 @@ if (ret < 0) { if (ret == -ENOENT) BT_ERR("Firmware file \"%s\" not found", - ATH3K_FIRMWARE); + ATH3K_FIRMWARE); else BT_ERR("Firmware file \"%s\" request failed (err=%d)", - ATH3K_FIRMWARE, ret); + ATH3K_FIRMWARE, ret); return ret; } --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btintel.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btintel.c @@ -441,7 +441,7 @@ return PTR_ERR(skb); } - if (skb->len != sizeof(*ver)) { + if (!skb || skb->len != sizeof(*ver)) { bt_dev_err(hdev, "Intel version event size mismatch"); kfree_skb(skb); return -EILSEQ; --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btmrvl_main.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btmrvl_main.c @@ -121,13 +121,6 @@ ((event->data[2] == MODULE_BROUGHT_UP) || (event->data[2] == MODULE_ALREADY_UP)) ? "Bring-up succeed" : "Bring-up failed"); - - if (event->length > 3 && event->data[3]) - priv->btmrvl_dev.dev_type = HCI_AMP; - else - priv->btmrvl_dev.dev_type = HCI_PRIMARY; - - BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type); } else if (priv->btmrvl_dev.sendcmdflag && event->data[1] == MODULE_SHUTDOWN_REQ) { BT_DBG("EVENT:%s", (event->data[2]) ? @@ -686,8 +679,6 @@ hdev->wakeup = btmrvl_wakeup; SET_HCIDEV_DEV(hdev, &card->func->dev); - hdev->dev_type = priv->btmrvl_dev.dev_type; - ret = hci_register_dev(hdev); if (ret < 0) { BT_ERR("Can not register HCI device"); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btmtk.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btmtk.c @@ -372,14 +372,18 @@ struct btmediatek_data *data = hci_get_priv(hdev); int err; - if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) + if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) { + kfree_skb(skb); return 0; + } switch (data->cd_info.state) { case HCI_DEVCOREDUMP_IDLE: err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE); - if (err < 0) + if (err < 0) { + kfree_skb(skb); break; + } data->cd_info.cnt = 0; /* It is supposed coredump can be done within 5 seconds */ @@ -405,9 +409,6 @@ break; } - if (err < 0) - kfree_skb(skb); - return err; } EXPORT_SYMBOL_GPL(btmtk_process_coredump); @@ -420,5 +421,6 @@ MODULE_FIRMWARE(FIRMWARE_MT7622); MODULE_FIRMWARE(FIRMWARE_MT7663); MODULE_FIRMWARE(FIRMWARE_MT7668); +MODULE_FIRMWARE(FIRMWARE_MT7922); MODULE_FIRMWARE(FIRMWARE_MT7961); MODULE_FIRMWARE(FIRMWARE_MT7925); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btmtk.h +++ linux-xilinx-6.8.0/drivers/bluetooth/btmtk.h @@ -4,6 +4,7 @@ #define FIRMWARE_MT7622 "mediatek/mt7622pr2h.bin" #define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin" #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" +#define FIRMWARE_MT7922 "mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin" #define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin" #define FIRMWARE_MT7925 "mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin" --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btnxpuart.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btnxpuart.c @@ -280,7 +280,7 @@ /* Default configurations */ #define DEFAULT_H2C_WAKEUP_MODE WAKEUP_METHOD_BREAK -#define DEFAULT_PS_MODE PS_MODE_DISABLE +#define DEFAULT_PS_MODE PS_MODE_ENABLE #define FW_INIT_BAUDRATE HCI_NXP_PRI_BAUDRATE static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode, @@ -1234,6 +1234,9 @@ ps_wakeup(nxpdev); serdev_device_close(nxpdev->serdev); + skb_queue_purge(&nxpdev->txq); + kfree_skb(nxpdev->rx_skb); + nxpdev->rx_skb = NULL; clear_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state); return 0; } --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btqca.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btqca.c @@ -99,7 +99,8 @@ { struct sk_buff *skb; struct edl_event_hdr *edl; - char cmd, build_label[QCA_FW_BUILD_VER_LEN]; + char *build_label; + char cmd; int build_lbl_len, err = 0; bt_dev_dbg(hdev, "QCA read fw build info"); @@ -114,6 +115,11 @@ return err; } + if (skb->len < sizeof(*edl)) { + err = -EILSEQ; + goto out; + } + edl = (struct edl_event_hdr *)(skb->data); if (!edl) { bt_dev_err(hdev, "QCA read fw build info with no header"); @@ -129,14 +135,27 @@ goto out; } + if (skb->len < sizeof(*edl) + 1) { + err = -EILSEQ; + goto out; + } + build_lbl_len = edl->data[0]; - if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) { - memcpy(build_label, edl->data + 1, build_lbl_len); - *(build_label + build_lbl_len) = '\0'; + + if (skb->len < sizeof(*edl) + 1 + build_lbl_len) { + err = -EILSEQ; + goto out; + } + + build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL); + if (!build_label) { + err = -ENOMEM; + goto out; } hci_set_fw_info(hdev, "%s", build_label); + kfree(build_label); out: kfree_skb(skb); return err; @@ -235,6 +254,11 @@ goto out; } + if (skb->len < 3) { + err = -EILSEQ; + goto out; + } + *bid = (edl->data[1] << 8) + edl->data[2]; bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid); @@ -265,9 +289,10 @@ } EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); -static void qca_tlv_check_data(struct hci_dev *hdev, +static int qca_tlv_check_data(struct hci_dev *hdev, struct qca_fw_config *config, - u8 *fw_data, enum qca_btsoc_type soc_type) + u8 *fw_data, size_t fw_size, + enum qca_btsoc_type soc_type) { const u8 *data; u32 type_len; @@ -277,12 +302,16 @@ struct tlv_type_patch *tlv_patch; struct tlv_type_nvm *tlv_nvm; uint8_t nvm_baud_rate = config->user_baud_rate; + u8 type; config->dnld_mode = QCA_SKIP_EVT_NONE; config->dnld_type = QCA_SKIP_EVT_NONE; switch (config->type) { case ELF_TYPE_PATCH: + if (fw_size < 7) + return -EINVAL; + config->dnld_mode = QCA_SKIP_EVT_VSE_CC; config->dnld_type = QCA_SKIP_EVT_VSE_CC; @@ -291,6 +320,9 @@ bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]); break; case TLV_TYPE_PATCH: + if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch)) + return -EINVAL; + tlv = (struct tlv_type_hdr *)fw_data; type_len = le32_to_cpu(tlv->type_len); tlv_patch = (struct tlv_type_patch *)tlv->data; @@ -330,25 +362,64 @@ break; case TLV_TYPE_NVM: + if (fw_size < sizeof(struct tlv_type_hdr)) + return -EINVAL; + tlv = (struct tlv_type_hdr *)fw_data; type_len = le32_to_cpu(tlv->type_len); - length = (type_len >> 8) & 0x00ffffff; + length = type_len >> 8; + type = type_len & 0xff; - BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff); + /* Some NVM files have more than one set of tags, only parse + * the first set when it has type 2 for now. When there is + * more than one set there is an enclosing header of type 4. + */ + if (type == 4) { + if (fw_size < 2 * sizeof(struct tlv_type_hdr)) + return -EINVAL; + + tlv++; + + type_len = le32_to_cpu(tlv->type_len); + length = type_len >> 8; + type = type_len & 0xff; + } + + BT_DBG("TLV Type\t\t : 0x%x", type); BT_DBG("Length\t\t : %d bytes", length); + if (type != 2) + break; + + if (fw_size < length + (tlv->data - fw_data)) + return -EINVAL; + idx = 0; data = tlv->data; - while (idx < length) { + while (idx < length - sizeof(struct tlv_type_nvm)) { tlv_nvm = (struct tlv_type_nvm *)(data + idx); tag_id = le16_to_cpu(tlv_nvm->tag_id); tag_len = le16_to_cpu(tlv_nvm->tag_len); + if (length < idx + sizeof(struct tlv_type_nvm) + tag_len) + return -EINVAL; + /* Update NVM tags as needed */ switch (tag_id) { + case EDL_TAG_ID_BD_ADDR: + if (tag_len != sizeof(bdaddr_t)) + return -EINVAL; + + memcpy(&config->bdaddr, tlv_nvm->data, sizeof(bdaddr_t)); + + break; + case EDL_TAG_ID_HCI: + if (tag_len < 3) + return -EINVAL; + /* HCI transport layer parameters * enabling software inband sleep * onto controller side. @@ -364,6 +435,9 @@ break; case EDL_TAG_ID_DEEP_SLEEP: + if (tag_len < 1) + return -EINVAL; + /* Sleep enable mask * enabling deep sleep feature on controller. */ @@ -372,14 +446,16 @@ break; } - idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len); + idx += sizeof(struct tlv_type_nvm) + tag_len; } break; default: BT_ERR("Unknown TLV type %d", config->type); - break; + return -EINVAL; } + + return 0; } static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, @@ -529,7 +605,9 @@ memcpy(data, fw->data, size); release_firmware(fw); - qca_tlv_check_data(hdev, config, data, soc_type); + ret = qca_tlv_check_data(hdev, config, data, size, soc_type); + if (ret) + goto out; segment = data; remain = size; @@ -612,6 +690,38 @@ } EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); +static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config) +{ + struct hci_rp_read_bd_addr *bda; + struct sk_buff *skb; + int err; + + if (bacmp(&hdev->public_addr, BDADDR_ANY)) + return 0; + + skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + err = PTR_ERR(skb); + bt_dev_err(hdev, "Failed to read device address (%d)", err); + return err; + } + + if (skb->len != sizeof(*bda)) { + bt_dev_err(hdev, "Device address length mismatch"); + kfree_skb(skb); + return -EIO; + } + + bda = (struct hci_rp_read_bd_addr *)skb->data; + if (!bacmp(&bda->bdaddr, &config->bdaddr)) + set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); + + kfree_skb(skb); + + return 0; +} + static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size, struct qca_btsoc_version ver, u8 rom_ver, u16 bid) { @@ -633,7 +743,7 @@ enum qca_btsoc_type soc_type, struct qca_btsoc_version ver, const char *firmware_name) { - struct qca_fw_config config; + struct qca_fw_config config = {}; int err; u8 rom_ver = 0; u32 soc_ver; @@ -818,6 +928,10 @@ break; } + err = qca_check_bdaddr(hdev, &config); + if (err) + return err; + bt_dev_info(hdev, "QCA setup on UART is completed"); return 0; @@ -826,11 +940,15 @@ int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) { + bdaddr_t bdaddr_swapped; struct sk_buff *skb; int err; - skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, bdaddr, - HCI_EV_VENDOR, HCI_INIT_TIMEOUT); + baswap(&bdaddr_swapped, bdaddr); + + skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, + &bdaddr_swapped, HCI_EV_VENDOR, + HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btqca.h +++ linux-xilinx-6.8.0/drivers/bluetooth/btqca.h @@ -29,6 +29,7 @@ #define EDL_PATCH_CONFIG_RES_EVT (0x00) #define QCA_DISABLE_LOGGING_SUB_OP (0x14) +#define EDL_TAG_ID_BD_ADDR 2 #define EDL_TAG_ID_HCI (17) #define EDL_TAG_ID_DEEP_SLEEP (27) @@ -47,7 +48,6 @@ #define get_soc_ver(soc_id, rom_ver) \ ((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver))) -#define QCA_FW_BUILD_VER_LEN 255 #define QCA_HSP_GF_SOC_ID 0x1200 #define QCA_HSP_GF_SOC_MASK 0x0000ff00 @@ -94,6 +94,7 @@ uint8_t user_baud_rate; enum qca_tlv_dnld_mode dnld_mode; enum qca_tlv_dnld_mode dnld_type; + bdaddr_t bdaddr; }; struct edl_event_hdr { --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btrsi.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btrsi.c @@ -134,7 +134,6 @@ hdev->bus = HCI_USB; hci_set_drvdata(hdev, h_adapter); - hdev->dev_type = HCI_PRIMARY; hdev->open = rsi_hci_open; hdev->close = rsi_hci_close; hdev->flush = rsi_hci_flush; --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btsdio.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btsdio.c @@ -32,9 +32,6 @@ /* Generic Bluetooth Type-B SDIO device */ { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) }, - /* Generic Bluetooth AMP controller */ - { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) }, - { } /* Terminating entry */ }; @@ -319,11 +316,6 @@ hdev->bus = HCI_SDIO; hci_set_drvdata(hdev, data); - if (id->class == SDIO_CLASS_BT_AMP) - hdev->dev_type = HCI_AMP; - else - hdev->dev_type = HCI_PRIMARY; - data->hdev = hdev; SET_HCIDEV_DEV(hdev, &func->dev); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/btusb.c +++ linux-xilinx-6.8.0/drivers/bluetooth/btusb.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -542,6 +543,8 @@ /* Realtek 8852BE Bluetooth devices */ { USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0x4853), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK | @@ -583,6 +586,9 @@ { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, + { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | + BTUSB_WIDEBAND_SPEECH | + BTUSB_VALID_LE_STATES }, { USB_DEVICE(0x0489, 0xe0e0), .driver_info = BTUSB_MEDIATEK | BTUSB_WIDEBAND_SPEECH | BTUSB_VALID_LE_STATES }, @@ -3273,7 +3279,6 @@ { struct btusb_data *data = hci_get_drvdata(hdev); u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); - struct sk_buff *skb_cd; switch (handle) { case 0xfc6f: /* Firmware dump from device */ @@ -3286,9 +3291,12 @@ * for backward compatibility, so we have to clone the packet * extraly for the in-kernel coredump support. */ - skb_cd = skb_clone(skb, GFP_ATOMIC); - if (skb_cd) - btmtk_process_coredump(hdev, skb_cd); + if (IS_ENABLED(CONFIG_DEV_COREDUMP)) { + struct sk_buff *skb_cd = skb_clone(skb, GFP_ATOMIC); + + if (skb_cd) + btmtk_process_coredump(hdev, skb_cd); + } fallthrough; case 0x05ff: /* Firmware debug logging 1 */ @@ -3366,6 +3374,35 @@ return 0; } +#define BTUSB_EDGE_LED_COMMAND 0xfc77 + +static void btusb_edge_set_led(struct hci_dev *hdev, bool state) +{ + struct sk_buff *skb; + u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 }; + + if (state) + config_led[1] = 0x01; + + skb = __hci_cmd_sync(hdev, BTUSB_EDGE_LED_COMMAND, sizeof(config_led), config_led, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) + BT_ERR("%s fail to set LED (%ld)", hdev->name, PTR_ERR(skb)); + else + kfree_skb(skb); +} + +static int btusb_edge_post_init(struct hci_dev *hdev) +{ + btusb_edge_set_led(hdev, true); + return 0; +} + +static int btusb_edge_shutdown(struct hci_dev *hdev) +{ + btusb_edge_set_led(hdev, false); + return 0; +} + static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, const bdaddr_t *bdaddr) { @@ -3461,13 +3498,12 @@ static void btusb_coredump_qca(struct hci_dev *hdev) { + int err; static const u8 param[] = { 0x26 }; - struct sk_buff *skb; - skb = __hci_cmd_sync(hdev, 0xfc0c, 1, param, HCI_CMD_TIMEOUT); - if (IS_ERR(skb)) - bt_dev_err(hdev, "%s: triggle crash failed (%ld)", __func__, PTR_ERR(skb)); - kfree_skb(skb); + err = __hci_cmd_send(hdev, 0xfc0c, 1, param); + if (err < 0) + bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err); } /* @@ -4311,11 +4347,6 @@ hdev->bus = HCI_USB; hci_set_drvdata(hdev, data); - if (id->driver_info & BTUSB_AMP) - hdev->dev_type = HCI_AMP; - else - hdev->dev_type = HCI_PRIMARY; - data->hdev = hdev; SET_HCIDEV_DEV(hdev, &intf->dev); @@ -4398,8 +4429,18 @@ btintel_set_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED); } - if (id->driver_info & BTUSB_MARVELL) + if (id->driver_info & BTUSB_MARVELL) { + struct pci_dev *pdev; hdev->set_bdaddr = btusb_set_bdaddr_marvell; + pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL); + if (!pdev) + pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL); + if (pdev) { + pci_dev_put(pdev); + hdev->post_init = btusb_edge_post_init; + hdev->shutdown = btusb_edge_shutdown; + } + } if (IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK) && (id->driver_info & BTUSB_MEDIATEK)) { @@ -4481,6 +4522,7 @@ set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks); set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks); + set_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &hdev->quirks); } if (!reset) --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_bcm4377.c +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_bcm4377.c @@ -495,6 +495,10 @@ * extended scanning * broken_mws_transport_config: Set to true if the chip erroneously claims to * support MWS Transport Configuration + * broken_le_ext_adv_report_phy: Set to true if this chip stuffs flags inside + * reserved bits of Primary/Secondary_PHY inside + * LE Extended Advertising Report events which + * have to be ignored * send_calibration: Optional callback to send calibration data * send_ptb: Callback to send "PTB" regulatory/calibration data */ @@ -513,6 +517,7 @@ unsigned long broken_ext_scan : 1; unsigned long broken_mws_transport_config : 1; unsigned long broken_le_coded : 1; + unsigned long broken_le_ext_adv_report_phy : 1; int (*send_calibration)(struct bcm4377_data *bcm4377); int (*send_ptb)(struct bcm4377_data *bcm4377, @@ -716,7 +721,7 @@ ring->events[msgid] = NULL; } - bitmap_release_region(ring->msgids, msgid, ring->n_entries); + bitmap_release_region(ring->msgids, msgid, 0); unlock: spin_unlock_irqrestore(&ring->lock, flags); @@ -2361,7 +2366,6 @@ bcm4377->hdev = hdev; hdev->bus = HCI_PCI; - hdev->dev_type = HCI_PRIMARY; hdev->open = bcm4377_hci_open; hdev->close = bcm4377_hci_close; hdev->send = bcm4377_hci_send_frame; @@ -2374,6 +2378,8 @@ set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks); if (bcm4377->hw->broken_le_coded) set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks); + if (bcm4377->hw->broken_le_ext_adv_report_phy) + set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks); pci_set_drvdata(pdev, bcm4377); hci_set_drvdata(hdev, bcm4377); @@ -2478,6 +2484,7 @@ .clear_pciecfg_subsystem_ctrl_bit19 = true, .broken_mws_transport_config = true, .broken_le_coded = true, + .broken_le_ext_adv_report_phy = true, .send_calibration = bcm4387_send_calibration, .send_ptb = bcm4378_send_ptb, }, --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_h5.c +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_h5.c @@ -113,6 +113,7 @@ int (*suspend)(struct h5 *h5); int (*resume)(struct h5 *h5); const struct acpi_gpio_mapping *acpi_gpio_map; + int sizeof_priv; }; struct h5_device_data { @@ -863,7 +864,8 @@ if (IS_ERR(h5->device_wake_gpio)) return PTR_ERR(h5->device_wake_gpio); - return hci_uart_register_device(&h5->serdev_hu, &h5p); + return hci_uart_register_device_priv(&h5->serdev_hu, &h5p, + h5->vnd->sizeof_priv); } static void h5_serdev_remove(struct serdev_device *serdev) @@ -1070,6 +1072,7 @@ .suspend = h5_btrtl_suspend, .resume = h5_btrtl_resume, .acpi_gpio_map = acpi_btrtl_gpios, + .sizeof_priv = sizeof(struct btrealtek_data), }; static const struct h5_device_data h5_data_rtl8822cs = { --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_ldisc.c +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_ldisc.c @@ -667,11 +667,6 @@ if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags)) set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); - if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) - hdev->dev_type = HCI_AMP; - else - hdev->dev_type = HCI_PRIMARY; - /* Only call open() for the protocol after hdev is fully initialized as * open() (or a timer/workqueue it starts) may attempt to reference it. */ @@ -722,7 +717,6 @@ { unsigned long valid_flags = BIT(HCI_UART_RAW_DEVICE) | BIT(HCI_UART_RESET_ON_INIT) | - BIT(HCI_UART_CREATE_AMP) | BIT(HCI_UART_INIT_PENDING) | BIT(HCI_UART_EXT_CONFIG) | BIT(HCI_UART_VND_DETECT); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_qca.c +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_qca.c @@ -7,7 +7,6 @@ * * Copyright (C) 2007 Texas Instruments, Inc. * Copyright (c) 2010, 2012, 2018 The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Acknowledgements: * This file is based on hci_ll.c, which was... @@ -226,6 +225,7 @@ struct qca_power *bt_power; u32 init_speed; u32 oper_speed; + bool bdaddr_property_broken; const char *firmware_name; }; @@ -1672,6 +1672,9 @@ struct hci_uart *hu = hci_get_drvdata(hdev); bool wakeup; + if (!hu->serdev) + return true; + /* BT SoC attached through the serial bus is handled by the serdev driver. * So we need to use the device handle of the serdev driver to get the * status of device may wakeup. @@ -1843,6 +1846,7 @@ const char *firmware_name = qca_get_firmware_name(hu); int ret; struct qca_btsoc_version ver; + struct qca_serdev *qcadev; const char *soc_name; ret = qca_check_speeds(hu); @@ -1904,16 +1908,9 @@ case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: - - /* Set BDA quirk bit for reading BDA value from fwnode property - * only if that property exist in DT. - */ - if (fwnode_property_present(dev_fwnode(hdev->dev.parent), "local-bd-address")) { - set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); - bt_dev_info(hdev, "setting quirk bit to read BDA from fwnode later"); - } else { - bt_dev_dbg(hdev, "local-bd-address` is not present in the devicetree so not setting quirk bit for BDA"); - } + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qcadev->bdaddr_property_broken) + set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks); hci_set_aosp_capable(hdev); @@ -1961,8 +1958,10 @@ qca_debugfs_init(hdev); hu->hdev->hw_error = qca_hw_error; hu->hdev->cmd_timeout = qca_cmd_timeout; - if (device_can_wakeup(hu->serdev->ctrl->dev.parent)) - hu->hdev->wakeup = qca_wakeup; + if (hu->serdev) { + if (device_can_wakeup(hu->serdev->ctrl->dev.parent)) + hu->hdev->wakeup = qca_wakeup; + } } else if (ret == -ENOENT) { /* No patch/nvm-config found, run with original fw/config */ set_bit(QCA_ROM_FW, &qca->flags); @@ -2295,6 +2294,9 @@ if (!qcadev->oper_speed) BT_DBG("UART will pick default operating speed"); + qcadev->bdaddr_property_broken = device_property_read_bool(&serdev->dev, + "qcom,local-bd-address-broken"); + if (data) qcadev->btsoc_type = data->soc_type; else @@ -2326,20 +2328,25 @@ qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR_OR_NULL(qcadev->bt_en) && + if (IS_ERR(qcadev->bt_en) && (data->soc_type == QCA_WCN6750 || data->soc_type == QCA_WCN6855)) { dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); - power_ctrl_enabled = false; + return PTR_ERR(qcadev->bt_en); } + if (!qcadev->bt_en) + power_ctrl_enabled = false; + qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", GPIOD_IN); - if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && + if (IS_ERR(qcadev->sw_ctrl) && (data->soc_type == QCA_WCN6750 || data->soc_type == QCA_WCN6855 || - data->soc_type == QCA_WCN7850)) - dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); + data->soc_type == QCA_WCN7850)) { + dev_err(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); + return PTR_ERR(qcadev->sw_ctrl); + } qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); if (IS_ERR(qcadev->susclk)) { @@ -2357,11 +2364,14 @@ default: qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR_OR_NULL(qcadev->bt_en)) { - dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); - power_ctrl_enabled = false; + if (IS_ERR(qcadev->bt_en)) { + dev_err(&serdev->dev, "failed to acquire enable gpio\n"); + return PTR_ERR(qcadev->bt_en); } + if (!qcadev->bt_en) + power_ctrl_enabled = false; + qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); if (IS_ERR(qcadev->susclk)) { dev_warn(&serdev->dev, "failed to acquire clk\n"); @@ -2440,15 +2450,27 @@ struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); struct hci_uart *hu = &qcadev->serdev_hu; struct hci_dev *hdev = hu->hdev; - struct qca_data *qca = hu->priv; const u8 ibs_wake_cmd[] = { 0xFD }; const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 }; if (qcadev->btsoc_type == QCA_QCA6390) { - if (test_bit(QCA_BT_OFF, &qca->flags) || - !test_bit(HCI_RUNNING, &hdev->flags)) + /* The purpose of sending the VSC is to reset SOC into a initial + * state and the state will ensure next hdev->setup() success. + * if HCI_QUIRK_NON_PERSISTENT_SETUP is set, it means that + * hdev->setup() can do its job regardless of SoC state, so + * don't need to send the VSC. + * if HCI_SETUP is set, it means that hdev->setup() was never + * invoked and the SOC is already in the initial state, so + * don't also need to send the VSC. + */ + if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks) || + hci_dev_test_flag(hdev, HCI_SETUP)) return; + /* The serdev must be in open state when conrol logic arrives + * here, so also fix the use-after-free issue caused by that + * the serdev is flushed or wrote after it is closed. + */ serdev_device_write_flush(serdev); ret = serdev_device_write_buf(serdev, ibs_wake_cmd, sizeof(ibs_wake_cmd)); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_serdev.c +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_serdev.c @@ -300,8 +300,9 @@ .write_wakeup = hci_uart_write_wakeup, }; -int hci_uart_register_device(struct hci_uart *hu, - const struct hci_uart_proto *p) +int hci_uart_register_device_priv(struct hci_uart *hu, + const struct hci_uart_proto *p, + int sizeof_priv) { int err; struct hci_dev *hdev; @@ -325,7 +326,7 @@ set_bit(HCI_UART_PROTO_READY, &hu->flags); /* Initialize and register HCI device */ - hdev = hci_alloc_dev(); + hdev = hci_alloc_dev_priv(sizeof_priv); if (!hdev) { BT_ERR("Can't allocate HCI device"); err = -ENOMEM; @@ -365,11 +366,6 @@ if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags)) set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks); - if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) - hdev->dev_type = HCI_AMP; - else - hdev->dev_type = HCI_PRIMARY; - if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) return 0; @@ -394,7 +390,7 @@ percpu_free_rwsem(&hu->proto_lock); return err; } -EXPORT_SYMBOL_GPL(hci_uart_register_device); +EXPORT_SYMBOL_GPL(hci_uart_register_device_priv); void hci_uart_unregister_device(struct hci_uart *hu) { --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_uart.h +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_uart.h @@ -37,7 +37,6 @@ #define HCI_UART_RAW_DEVICE 0 #define HCI_UART_RESET_ON_INIT 1 -#define HCI_UART_CREATE_AMP 2 #define HCI_UART_INIT_PENDING 3 #define HCI_UART_EXT_CONFIG 4 #define HCI_UART_VND_DETECT 5 @@ -97,7 +96,17 @@ int hci_uart_register_proto(const struct hci_uart_proto *p); int hci_uart_unregister_proto(const struct hci_uart_proto *p); -int hci_uart_register_device(struct hci_uart *hu, const struct hci_uart_proto *p); + +int hci_uart_register_device_priv(struct hci_uart *hu, + const struct hci_uart_proto *p, + int sizeof_priv); + +static inline int hci_uart_register_device(struct hci_uart *hu, + const struct hci_uart_proto *p) +{ + return hci_uart_register_device_priv(hu, p, 0); +} + void hci_uart_unregister_device(struct hci_uart *hu); int hci_uart_tx_wakeup(struct hci_uart *hu); --- linux-xilinx-6.8.0.orig/drivers/bluetooth/hci_vhci.c +++ linux-xilinx-6.8.0/drivers/bluetooth/hci_vhci.c @@ -384,17 +384,10 @@ { struct hci_dev *hdev; struct sk_buff *skb; - __u8 dev_type; if (data->hdev) return -EBADFD; - /* bits 0-1 are dev_type (Primary or AMP) */ - dev_type = opcode & 0x03; - - if (dev_type != HCI_PRIMARY && dev_type != HCI_AMP) - return -EINVAL; - /* bits 2-5 are reserved (must be zero) */ if (opcode & 0x3c) return -EINVAL; @@ -412,7 +405,6 @@ data->hdev = hdev; hdev->bus = HCI_VIRTUAL; - hdev->dev_type = dev_type; hci_set_drvdata(hdev, data); hdev->open = vhci_open_dev; @@ -634,7 +626,7 @@ struct vhci_data *data = container_of(work, struct vhci_data, open_timeout.work); - vhci_create_device(data, amp ? HCI_AMP : HCI_PRIMARY); + vhci_create_device(data, 0x00); } static int vhci_open(struct inode *inode, struct file *file) --- linux-xilinx-6.8.0.orig/drivers/bluetooth/virtio_bt.c +++ linux-xilinx-6.8.0/drivers/bluetooth/virtio_bt.c @@ -274,7 +274,6 @@ switch (type) { case VIRTIO_BT_CONFIG_TYPE_PRIMARY: - case VIRTIO_BT_CONFIG_TYPE_AMP: break; default: return -EINVAL; @@ -303,7 +302,6 @@ vbt->hdev = hdev; hdev->bus = HCI_VIRTIO; - hdev->dev_type = type; hci_set_drvdata(hdev, vbt); hdev->open = virtbt_open; --- linux-xilinx-6.8.0.orig/drivers/bus/Kconfig +++ linux-xilinx-6.8.0/drivers/bus/Kconfig @@ -186,11 +186,12 @@ config TEGRA_ACONNECT tristate "Tegra ACONNECT Bus Driver" - depends on ARCH_TEGRA_210_SOC + depends on ARCH_TEGRA depends on OF && PM help Driver for the Tegra ACONNECT bus which is used to interface with - the devices inside the Audio Processing Engine (APE) for Tegra210. + the devices inside the Audio Processing Engine (APE) for + Tegra210 and later. config TEGRA_GMI tristate "Tegra Generic Memory Interface bus driver" --- linux-xilinx-6.8.0.orig/drivers/bus/mhi/ep/main.c +++ linux-xilinx-6.8.0/drivers/bus/mhi/ep/main.c @@ -1496,7 +1496,7 @@ mhi_cntrl->ring_item_cache = kmem_cache_create("mhi_ep_ring_item", sizeof(struct mhi_ep_ring_item), 0, 0, NULL); - if (!mhi_cntrl->ev_ring_el_cache) { + if (!mhi_cntrl->ring_item_cache) { ret = -ENOMEM; goto err_destroy_tre_buf_cache; } --- linux-xilinx-6.8.0.orig/drivers/bus/mhi/host/init.c +++ linux-xilinx-6.8.0/drivers/bus/mhi/host/init.c @@ -62,6 +62,7 @@ [MHI_PM_STATE_FW_DL_ERR] = "Firmware Download Error", [MHI_PM_STATE_SYS_ERR_DETECT] = "SYS ERROR Detect", [MHI_PM_STATE_SYS_ERR_PROCESS] = "SYS ERROR Process", + [MHI_PM_STATE_SYS_ERR_FAIL] = "SYS ERROR Failure", [MHI_PM_STATE_SHUTDOWN_PROCESS] = "SHUTDOWN Process", [MHI_PM_STATE_LD_ERR_FATAL_DETECT] = "Linkdown or Error Fatal Detect", }; --- linux-xilinx-6.8.0.orig/drivers/bus/mhi/host/internal.h +++ linux-xilinx-6.8.0/drivers/bus/mhi/host/internal.h @@ -88,6 +88,7 @@ MHI_PM_STATE_FW_DL_ERR, MHI_PM_STATE_SYS_ERR_DETECT, MHI_PM_STATE_SYS_ERR_PROCESS, + MHI_PM_STATE_SYS_ERR_FAIL, MHI_PM_STATE_SHUTDOWN_PROCESS, MHI_PM_STATE_LD_ERR_FATAL_DETECT, MHI_PM_STATE_MAX @@ -104,14 +105,16 @@ #define MHI_PM_FW_DL_ERR BIT(7) #define MHI_PM_SYS_ERR_DETECT BIT(8) #define MHI_PM_SYS_ERR_PROCESS BIT(9) -#define MHI_PM_SHUTDOWN_PROCESS BIT(10) +#define MHI_PM_SYS_ERR_FAIL BIT(10) +#define MHI_PM_SHUTDOWN_PROCESS BIT(11) /* link not accessible */ -#define MHI_PM_LD_ERR_FATAL_DETECT BIT(11) +#define MHI_PM_LD_ERR_FATAL_DETECT BIT(12) #define MHI_REG_ACCESS_VALID(pm_state) ((pm_state & (MHI_PM_POR | MHI_PM_M0 | \ MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \ MHI_PM_SYS_ERR_DETECT | MHI_PM_SYS_ERR_PROCESS | \ - MHI_PM_SHUTDOWN_PROCESS | MHI_PM_FW_DL_ERR))) + MHI_PM_SYS_ERR_FAIL | MHI_PM_SHUTDOWN_PROCESS | \ + MHI_PM_FW_DL_ERR))) #define MHI_PM_IN_ERROR_STATE(pm_state) (pm_state >= MHI_PM_FW_DL_ERR) #define MHI_PM_IN_FATAL_STATE(pm_state) (pm_state == MHI_PM_LD_ERR_FATAL_DETECT) #define MHI_DB_ACCESS_VALID(mhi_cntrl) (mhi_cntrl->pm_state & mhi_cntrl->db_access) --- linux-xilinx-6.8.0.orig/drivers/bus/mhi/host/pm.c +++ linux-xilinx-6.8.0/drivers/bus/mhi/host/pm.c @@ -36,7 +36,10 @@ * M0 <--> M0 * M0 -> FW_DL_ERR * M0 -> M3_ENTER -> M3 -> M3_EXIT --> M0 - * L1: SYS_ERR_DETECT -> SYS_ERR_PROCESS --> POR + * L1: SYS_ERR_DETECT -> SYS_ERR_PROCESS + * SYS_ERR_PROCESS -> SYS_ERR_FAIL + * SYS_ERR_FAIL -> SYS_ERR_DETECT + * SYS_ERR_PROCESS --> POR * L2: SHUTDOWN_PROCESS -> LD_ERR_FATAL_DETECT * SHUTDOWN_PROCESS -> DISABLE * L3: LD_ERR_FATAL_DETECT <--> LD_ERR_FATAL_DETECT @@ -93,7 +96,12 @@ }, { MHI_PM_SYS_ERR_PROCESS, - MHI_PM_POR | MHI_PM_SHUTDOWN_PROCESS | + MHI_PM_POR | MHI_PM_SYS_ERR_FAIL | MHI_PM_SHUTDOWN_PROCESS | + MHI_PM_LD_ERR_FATAL_DETECT + }, + { + MHI_PM_SYS_ERR_FAIL, + MHI_PM_SYS_ERR_DETECT | MHI_PM_SHUTDOWN_PROCESS | MHI_PM_LD_ERR_FATAL_DETECT }, /* L2 States */ @@ -629,7 +637,13 @@ !in_reset, timeout); if (!ret || in_reset) { dev_err(dev, "Device failed to exit MHI Reset state\n"); - goto exit_sys_error_transition; + write_lock_irq(&mhi_cntrl->pm_lock); + cur_state = mhi_tryset_pm_state(mhi_cntrl, + MHI_PM_SYS_ERR_FAIL); + write_unlock_irq(&mhi_cntrl->pm_lock); + /* Shutdown may have occurred, otherwise cleanup now */ + if (cur_state != MHI_PM_SYS_ERR_FAIL) + goto exit_sys_error_transition; } /* --- linux-xilinx-6.8.0.orig/drivers/cdrom/cdrom.c +++ linux-xilinx-6.8.0/drivers/cdrom/cdrom.c @@ -282,7 +282,7 @@ /* default compatibility mode */ static bool autoclose=1; static bool autoeject; -static bool lockdoor = 1; +static bool lockdoor = 0; /* will we ever get to use this... sigh. */ static bool check_media_type; /* automatically restart mrw format */ @@ -2358,7 +2358,7 @@ return -EFAULT; tmp_info.media_flags = 0; - if (tmp_info.last_media_change - cdi->last_media_change_ms < 0) + if (cdi->last_media_change_ms > tmp_info.last_media_change) tmp_info.media_flags |= MEDIA_CHANGED_FLAG; tmp_info.last_media_change = cdi->last_media_change_ms; --- linux-xilinx-6.8.0.orig/drivers/cdx/Kconfig +++ linux-xilinx-6.8.0/drivers/cdx/Kconfig @@ -8,6 +8,7 @@ config CDX_BUS bool "CDX Bus driver" depends on OF && ARM64 + select GENERIC_MSI_IRQ_DOMAIN help Driver to enable Composable DMA Transfer(CDX) Bus. CDX bus exposes Fabric devices which uses composable DMA IP to the --- linux-xilinx-6.8.0.orig/drivers/cdx/Makefile +++ linux-xilinx-6.8.0/drivers/cdx/Makefile @@ -7,4 +7,4 @@ ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CDX_BUS -obj-$(CONFIG_CDX_BUS) += cdx.o controller/ +obj-$(CONFIG_CDX_BUS) += cdx.o cdx_msi.o controller/ --- linux-xilinx-6.8.0.orig/drivers/cdx/cdx.c +++ linux-xilinx-6.8.0/drivers/cdx/cdx.c @@ -56,6 +56,7 @@ */ #include +#include #include #include #include @@ -787,6 +788,7 @@ /* Populate CDX dev params */ cdx_dev->req_id = dev_params->req_id; + cdx_dev->msi_dev_id = dev_params->msi_dev_id; cdx_dev->vendor = dev_params->vendor; cdx_dev->device = dev_params->device; cdx_dev->subsystem_vendor = dev_params->subsys_vendor; @@ -804,12 +806,19 @@ cdx_dev->dev.bus = &cdx_bus_type; cdx_dev->dev.dma_mask = &cdx_dev->dma_mask; cdx_dev->dev.release = cdx_device_release; + cdx_dev->msi_write_pending = false; + mutex_init(&cdx_dev->irqchip_lock); /* Set Name */ dev_set_name(&cdx_dev->dev, "cdx-%02x:%02x", ((cdx->id << CDX_CONTROLLER_ID_SHIFT) | (cdx_dev->bus_num & CDX_BUS_NUM_MASK)), cdx_dev->dev_num); + if (cdx->msi_domain) { + cdx_dev->num_msi = dev_params->num_msi; + dev_set_msi_domain(&cdx_dev->dev, cdx->msi_domain); + } + ret = device_add(&cdx_dev->dev); if (ret) { dev_err(&cdx_dev->dev, --- linux-xilinx-6.8.0.orig/drivers/cdx/cdx.h +++ linux-xilinx-6.8.0/drivers/cdx/cdx.h @@ -25,6 +25,8 @@ * @req_id: Requestor ID associated with CDX device * @class: Class of the CDX Device * @revision: Revision of the CDX device + * @msi_dev_id: MSI device ID associated with CDX device + * @num_msi: Number of MSI's supported by the device */ struct cdx_dev_params { struct cdx_controller *cdx; @@ -40,6 +42,8 @@ u32 req_id; u32 class; u8 revision; + u32 msi_dev_id; + u32 num_msi; }; /** @@ -79,4 +83,12 @@ */ struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num); +/** + * cdx_msi_domain_init - Init the CDX bus MSI domain. + * @dev: Device of the CDX bus controller + * + * Return: CDX MSI domain, NULL on failure + */ +struct irq_domain *cdx_msi_domain_init(struct device *dev); + #endif /* _CDX_H_ */ --- linux-xilinx-6.8.0.orig/drivers/cdx/cdx_msi.c +++ linux-xilinx-6.8.0/drivers/cdx/cdx_msi.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD CDX bus driver MSI support + * + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cdx.h" + +static void cdx_msi_write_msg(struct irq_data *irq_data, + struct msi_msg *msg) +{ + struct msi_desc *msi_desc = irq_data_get_msi_desc(irq_data); + struct cdx_device *cdx_dev = to_cdx_device(msi_desc->dev); + + /* We would not operate on msg here rather we wait for + * irq_bus_sync_unlock() to be called from preemptible + * task context. + */ + msi_desc->msg = *msg; + cdx_dev->msi_write_pending = true; +} + +static void cdx_msi_write_irq_lock(struct irq_data *irq_data) +{ + struct msi_desc *msi_desc = irq_data_get_msi_desc(irq_data); + struct cdx_device *cdx_dev = to_cdx_device(msi_desc->dev); + + mutex_lock(&cdx_dev->irqchip_lock); +} + +static void cdx_msi_write_irq_unlock(struct irq_data *irq_data) +{ + struct msi_desc *msi_desc = irq_data_get_msi_desc(irq_data); + struct cdx_device *cdx_dev = to_cdx_device(msi_desc->dev); + struct cdx_controller *cdx = cdx_dev->cdx; + struct cdx_device_config dev_config; + int ret; + + if (!cdx_dev->msi_write_pending) { + mutex_unlock(&cdx_dev->irqchip_lock); + return; + } + + cdx_dev->msi_write_pending = false; + mutex_unlock(&cdx_dev->irqchip_lock); + + dev_config.msi.msi_index = msi_desc->msi_index; + dev_config.msi.data = msi_desc->msg.data; + dev_config.msi.addr = ((u64)(msi_desc->msg.address_hi) << 32) | + msi_desc->msg.address_lo; + + dev_config.type = CDX_DEV_MSI_CONF; + ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num, cdx_dev->dev_num, + &dev_config); + if (ret) + dev_err(&cdx_dev->dev, "Write MSI failed to CDX controller\n"); +} + +int cdx_enable_msi(struct cdx_device *cdx_dev) +{ + struct cdx_controller *cdx = cdx_dev->cdx; + struct cdx_device_config dev_config; + int ret; + + dev_config.type = CDX_DEV_MSI_ENABLE; + dev_config.msi_enable = true; + ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num, cdx_dev->dev_num, + &dev_config); + if (ret) + dev_err(&cdx_dev->dev, "MSI enable failed\n"); + + return ret; +} +EXPORT_SYMBOL_GPL(cdx_enable_msi); + +void cdx_disable_msi(struct cdx_device *cdx_dev) +{ + struct cdx_controller *cdx = cdx_dev->cdx; + struct cdx_device_config dev_config; + int ret; + + dev_config.type = CDX_DEV_MSI_ENABLE; + dev_config.msi_enable = false; + ret = cdx->ops->dev_configure(cdx, cdx_dev->bus_num, cdx_dev->dev_num, + &dev_config); + if (ret) + dev_err(&cdx_dev->dev, "MSI disable failed\n"); +} +EXPORT_SYMBOL_GPL(cdx_disable_msi); + +static struct irq_chip cdx_msi_irq_chip = { + .name = "CDX-MSI", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = msi_domain_set_affinity, + .irq_write_msi_msg = cdx_msi_write_msg, + .irq_bus_lock = cdx_msi_write_irq_lock, + .irq_bus_sync_unlock = cdx_msi_write_irq_unlock +}; + +int cdx_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count) +{ + int ret; + + ret = msi_setup_device_data(dev); + if (ret) + return ret; + + ret = msi_domain_alloc_irqs_range(dev, MSI_DEFAULT_DOMAIN, + 0, irq_count - 1); + if (ret) + dev_err(dev, "Failed to allocate IRQs: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(cdx_msi_domain_alloc_irqs); + +/* Convert an msi_desc to a globally unique identifier. */ +static irq_hw_number_t cdx_domain_calc_hwirq(struct cdx_device *dev, + struct msi_desc *desc) +{ + return ((irq_hw_number_t)dev->msi_dev_id << 10) | desc->msi_index; +} + +static void cdx_msi_set_desc(msi_alloc_info_t *arg, + struct msi_desc *desc) +{ + arg->desc = desc; + arg->hwirq = cdx_domain_calc_hwirq(to_cdx_device(desc->dev), desc); +} + +static int cdx_msi_prepare(struct irq_domain *msi_domain, + struct device *dev, + int nvec, msi_alloc_info_t *info) +{ + struct cdx_device *cdx_dev = to_cdx_device(dev); + struct device *parent = dev->parent; + struct msi_domain_info *msi_info; + u32 dev_id = 0; + int ret; + + /* Retrieve device ID from requestor ID using parent device */ + ret = of_map_id(parent->of_node, cdx_dev->msi_dev_id, "msi-map", + "msi-map-mask", NULL, &dev_id); + if (ret) { + dev_err(dev, "of_map_id failed for MSI: %d\n", ret); + return ret; + } + + /* Set the device Id to be passed to the GIC-ITS */ + info->scratchpad[0].ul = dev_id; + + msi_info = msi_get_domain_info(msi_domain->parent); + + return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info); +} + +static struct msi_domain_ops cdx_msi_ops = { + .msi_prepare = cdx_msi_prepare, + .set_desc = cdx_msi_set_desc +}; + +static struct msi_domain_info cdx_msi_domain_info = { + .ops = &cdx_msi_ops, + .chip = &cdx_msi_irq_chip, + .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS | MSI_FLAG_FREE_MSI_DESCS +}; + +struct irq_domain *cdx_msi_domain_init(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct fwnode_handle *fwnode_handle; + struct irq_domain *cdx_msi_domain; + struct device_node *parent_node; + struct irq_domain *parent; + + fwnode_handle = of_node_to_fwnode(np); + + parent_node = of_parse_phandle(np, "msi-map", 1); + if (!parent_node) { + dev_err(dev, "msi-map not present on cdx controller\n"); + return NULL; + } + + parent = irq_find_matching_fwnode(of_node_to_fwnode(parent_node), + DOMAIN_BUS_NEXUS); + if (!parent || !msi_get_domain_info(parent)) { + dev_err(dev, "unable to locate ITS domain\n"); + return NULL; + } + + cdx_msi_domain = msi_create_irq_domain(fwnode_handle, &cdx_msi_domain_info, + parent); + if (!cdx_msi_domain) { + dev_err(dev, "unable to create CDX-MSI domain\n"); + return NULL; + } + + dev_dbg(dev, "CDX-MSI domain created\n"); + + return cdx_msi_domain; +} +EXPORT_SYMBOL_GPL(cdx_msi_domain_init); --- linux-xilinx-6.8.0.orig/drivers/cdx/controller/cdx_controller.c +++ linux-xilinx-6.8.0/drivers/cdx/controller/cdx_controller.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "cdx_controller.h" #include "../cdx.h" @@ -60,9 +61,20 @@ u8 bus_num, u8 dev_num, struct cdx_device_config *dev_config) { + u16 msi_index; int ret = 0; + u32 data; + u64 addr; switch (dev_config->type) { + case CDX_DEV_MSI_CONF: + msi_index = dev_config->msi.msi_index; + data = dev_config->msi.data; + addr = dev_config->msi.addr; + + ret = cdx_mcdi_write_msi(cdx->priv, bus_num, dev_num, + msi_index, addr, data); + break; case CDX_DEV_RESET_CONF: ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num); break; @@ -70,6 +82,10 @@ ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num, dev_config->bus_master_enable); break; + case CDX_DEV_MSI_ENABLE: + ret = cdx_mcdi_msi_enable(cdx->priv, bus_num, dev_num, + dev_config->msi_enable); + break; default: ret = -EINVAL; } @@ -178,6 +194,14 @@ cdx->priv = cdx_mcdi; cdx->ops = &cdx_ops; + /* Create MSI domain */ + cdx->msi_domain = cdx_msi_domain_init(&pdev->dev); + if (!cdx->msi_domain) { + dev_err(&pdev->dev, "cdx_msi_domain_init() failed"); + ret = -ENODEV; + goto cdx_msi_fail; + } + ret = cdx_setup_rpmsg(pdev); if (ret) { if (ret != -EPROBE_DEFER) @@ -189,6 +213,8 @@ return 0; cdx_rpmsg_fail: + irq_domain_remove(cdx->msi_domain); +cdx_msi_fail: kfree(cdx); cdx_alloc_fail: cdx_mcdi_finish(cdx_mcdi); @@ -205,6 +231,7 @@ cdx_destroy_rpmsg(pdev); + irq_domain_remove(cdx->msi_domain); kfree(cdx); cdx_mcdi_finish(cdx_mcdi); @@ -253,3 +280,4 @@ MODULE_DESCRIPTION("CDX controller for AMD devices"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(CDX_BUS_CONTROLLER); +MODULE_IMPORT_NS(CDX_BUS); --- linux-xilinx-6.8.0.orig/drivers/cdx/controller/mc_cdx_pcol.h +++ linux-xilinx-6.8.0/drivers/cdx/controller/mc_cdx_pcol.h @@ -455,6 +455,12 @@ #define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_REQUESTER_ID_OFST 84 #define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_REQUESTER_ID_LEN 4 +/* MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2 msgresponse */ +#define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_LEN 92 +/* Requester ID used by device for GIC ITS DeviceID */ +#define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_REQUESTER_DEVICE_ID_OFST 88 +#define MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_REQUESTER_DEVICE_ID_LEN 4 + /***********************************/ /* * MC_CMD_CDX_BUS_DOWN @@ -617,6 +623,64 @@ #define MC_CMD_CDX_DEVICE_CONTROL_GET_OUT_MMIO_REGIONS_ENABLE_WIDTH 1 /***********************************/ +/* + * MC_CMD_CDX_DEVICE_WRITE_MSI_MSG + * Populates the MSI message to be used by the hardware to raise the specified + * interrupt vector. Versal-net implementation specific limitations are that + * only 4 CDX devices with MSI interrupt capability are supported and all + * vectors within a device must use the same write address. The command will + * return EINVAL if any of these limitations is violated. + */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG 0x9 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_MSGSET 0x9 +#undef MC_CMD_0x9_PRIVILEGE_CTG + +#define MC_CMD_0x9_PRIVILEGE_CTG SRIOV_CTG_ADMIN + +/* MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN msgrequest */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_LEN 28 +/* Device bus number, in range 0 to BUS_COUNT-1 */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_BUS_OFST 0 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_BUS_LEN 4 +/* Device number relative to the bus, in range 0 to DEVICE_COUNT-1 for that bus */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_DEVICE_OFST 4 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_DEVICE_LEN 4 +/* + * Device-relative MSI vector number. Must be < MSI_COUNT reported for the + * device. + */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_VECTOR_OFST 8 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_VECTOR_LEN 4 +/* Reserved (alignment) */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_RESERVED_OFST 12 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_RESERVED_LEN 4 +/* + * MSI address to be used by the hardware. Typically, on ARM systems this + * address is translated by the IOMMU (if enabled) and it is the responsibility + * of the entity managing the IOMMU (APU kernel) to supply the correct IOVA + * here. + */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_OFST 16 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_LEN 8 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_LO_OFST 16 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_LO_LEN 4 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_LO_LBN 128 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_LO_WIDTH 32 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_HI_OFST 20 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_HI_LEN 4 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_HI_LBN 160 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS_HI_WIDTH 32 +/* + * MSI data to be used by the hardware. On versal-net, only the lower 16-bits + * are used, the remaining bits are ignored and should be set to zero. + */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_DATA_OFST 24 +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_DATA_LEN 4 + +/* MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_OUT msgresponse */ +#define MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_OUT_LEN 0 + +/***********************************/ /* MC_CMD_V2_EXTN - Encapsulation for a v2 extended command */ #define MC_CMD_V2_EXTN 0x7f --- linux-xilinx-6.8.0.orig/drivers/cdx/controller/mcdi_functions.c +++ linux-xilinx-6.8.0/drivers/cdx/controller/mcdi_functions.c @@ -49,7 +49,7 @@ u8 bus_num, u8 dev_num, struct cdx_dev_params *dev_params) { - MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_LEN); + MCDI_DECLARE_BUF(outbuf, MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_LEN); MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_IN_LEN); struct resource *res = &dev_params->res[0]; size_t outlen; @@ -64,7 +64,7 @@ if (ret) return ret; - if (outlen != MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_LEN) + if (outlen != MC_CMD_CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_LEN) return -EIO; dev_params->bus_num = bus_num; @@ -73,6 +73,9 @@ req_id = MCDI_DWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_REQUESTER_ID); dev_params->req_id = req_id; + dev_params->msi_dev_id = MCDI_DWORD(outbuf, + CDX_BUS_GET_DEVICE_CONFIG_OUT_V2_REQUESTER_DEVICE_ID); + dev_params->res_count = 0; if (MCDI_QWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MMIO_REGION0_SIZE) != 0) { res[dev_params->res_count].start = @@ -120,6 +123,7 @@ dev_params->vendor = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_VENDOR_ID); dev_params->device = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_DEVICE_ID); + dev_params->num_msi = MCDI_DWORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_MSI_COUNT); dev_params->subsys_vendor = MCDI_WORD(outbuf, CDX_BUS_GET_DEVICE_CONFIG_OUT_SUBSYS_VENDOR_ID); dev_params->subsys_device = MCDI_WORD(outbuf, @@ -155,6 +159,24 @@ return ret; } +int cdx_mcdi_write_msi(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num, + u32 msi_vector, u64 msi_address, u32 msi_data) +{ + MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_WRITE_MSI_MSG_IN_LEN); + int ret; + + MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_BUS, bus_num); + MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_DEVICE, dev_num); + MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_VECTOR, msi_vector); + MCDI_SET_QWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_ADDRESS, msi_address); + MCDI_SET_DWORD(inbuf, CDX_DEVICE_WRITE_MSI_MSG_IN_MSI_DATA, msi_data); + + ret = cdx_mcdi_rpc(cdx, MC_CMD_CDX_DEVICE_WRITE_MSI_MSG, inbuf, sizeof(inbuf), + NULL, 0, NULL); + + return ret; +} + int cdx_mcdi_reset_device(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num) { MCDI_DECLARE_BUF(inbuf, MC_CMD_CDX_DEVICE_RESET_IN_LEN); @@ -226,3 +248,10 @@ return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable, MC_CMD_CDX_DEVICE_CONTROL_SET_IN_BUS_MASTER_ENABLE_LBN); } + +int cdx_mcdi_msi_enable(struct cdx_mcdi *cdx, u8 bus_num, + u8 dev_num, bool enable) +{ + return cdx_mcdi_ctrl_flag_set(cdx, bus_num, dev_num, enable, + MC_CMD_CDX_DEVICE_CONTROL_SET_IN_MSI_ENABLE_LBN); +} --- linux-xilinx-6.8.0.orig/drivers/cdx/controller/mcdi_functions.h +++ linux-xilinx-6.8.0/drivers/cdx/controller/mcdi_functions.h @@ -48,6 +48,26 @@ struct cdx_dev_params *dev_params); /** + * cdx_mcdi_write_msi - Write MSI configuration for CDX device + * @cdx: pointer to MCDI interface. + * @bus_num: Bus number. + * @dev_num: Device number. + * @msi_vector: Device-relative MSI vector number. + * Must be < MSI_COUNT reported for the device. + * @msi_address: MSI address to be used by the hardware. Typically, on ARM + * systems this address is translated by the IOMMU (if enabled) and + * it is the responsibility of the entity managing the IOMMU (APU kernel) + * to supply the correct IOVA here. + * @msi_data: MSI data to be used by the hardware. On versal-net, only the + * lower 16-bits are used, the remaining bits are ignored and should be + * set to zero. + * + * Return: 0 on success, <0 on failure + */ +int cdx_mcdi_write_msi(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num, + u32 msi_vector, u64 msi_address, u32 msi_data); + +/** * cdx_mcdi_bus_enable - Enable CDX bus represented by bus_num * @cdx: pointer to MCDI interface. * @bus_num: Bus number. @@ -89,4 +109,17 @@ int cdx_mcdi_bus_master_enable(struct cdx_mcdi *cdx, u8 bus_num, u8 dev_num, bool enable); +/** + * cdx_mcdi_msi_enable - Enable/Disable MSIs for cdx device represented + * by bus_num:dev_num + * @cdx: pointer to MCDI interface. + * @bus_num: Bus number. + * @dev_num: Device number. + * @enable: Enable msi's if set, disable otherwise. + * + * Return: 0 on success, <0 on failure + */ +int cdx_mcdi_msi_enable(struct cdx_mcdi *cdx, u8 bus_num, + u8 dev_num, bool enable); + #endif /* CDX_MCDI_FUNCTIONS_H */ --- linux-xilinx-6.8.0.orig/drivers/char/hpet.c +++ linux-xilinx-6.8.0/drivers/char/hpet.c @@ -270,8 +270,13 @@ if (!devp->hd_ireqfreq) return -EIO; - if (count < sizeof(unsigned long)) - return -EINVAL; + if (in_compat_syscall()) { + if (count < sizeof(compat_ulong_t)) + return -EINVAL; + } else { + if (count < sizeof(unsigned long)) + return -EINVAL; + } add_wait_queue(&devp->hd_waitqueue, &wait); @@ -295,9 +300,16 @@ schedule(); } - retval = put_user(data, (unsigned long __user *)buf); - if (!retval) - retval = sizeof(unsigned long); + if (in_compat_syscall()) { + retval = put_user(data, (compat_ulong_t __user *)buf); + if (!retval) + retval = sizeof(compat_ulong_t); + } else { + retval = put_user(data, (unsigned long __user *)buf); + if (!retval) + retval = sizeof(unsigned long); + } + out: __set_current_state(TASK_RUNNING); remove_wait_queue(&devp->hd_waitqueue, &wait); @@ -652,12 +664,24 @@ unsigned short hi_timer; }; +/* 32-bit types would lead to different command codes which should be + * translated into 64-bit ones before passed to hpet_ioctl_common + */ +#define COMPAT_HPET_INFO _IOR('h', 0x03, struct compat_hpet_info) +#define COMPAT_HPET_IRQFREQ _IOW('h', 0x6, compat_ulong_t) + static long hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct hpet_info info; int err; + if (cmd == COMPAT_HPET_INFO) + cmd = HPET_INFO; + + if (cmd == COMPAT_HPET_IRQFREQ) + cmd = HPET_IRQFREQ; + mutex_lock(&hpet_mutex); err = hpet_ioctl_common(file->private_data, cmd, arg, &info); mutex_unlock(&hpet_mutex); --- linux-xilinx-6.8.0.orig/drivers/char/hw_random/stm32-rng.c +++ linux-xilinx-6.8.0/drivers/char/hw_random/stm32-rng.c @@ -220,7 +220,8 @@ if (err && i > RNG_NB_RECOVER_TRIES) { dev_err((struct device *)priv->rng.priv, "Couldn't recover from seed error\n"); - return -ENOTRECOVERABLE; + retval = -ENOTRECOVERABLE; + goto exit_rpm; } continue; @@ -238,7 +239,8 @@ if (err && i > RNG_NB_RECOVER_TRIES) { dev_err((struct device *)priv->rng.priv, "Couldn't recover from seed error"); - return -ENOTRECOVERABLE; + retval = -ENOTRECOVERABLE; + goto exit_rpm; } continue; @@ -250,6 +252,7 @@ max -= sizeof(u32); } +exit_rpm: pm_runtime_mark_last_busy((struct device *) priv->rng.priv); pm_runtime_put_sync_autosuspend((struct device *) priv->rng.priv); @@ -353,13 +356,15 @@ err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_SR, reg, reg & RNG_SR_DRDY, 10, 100000); - if (err | (reg & ~RNG_SR_DRDY)) { + if (err || (reg & ~RNG_SR_DRDY)) { clk_disable_unprepare(priv->clk); dev_err((struct device *)priv->rng.priv, "%s: timeout:%x SR: %x!\n", __func__, err, reg); return -EINVAL; } + clk_disable_unprepare(priv->clk); + return 0; } @@ -384,6 +389,11 @@ static int __maybe_unused stm32_rng_suspend(struct device *dev) { struct stm32_rng_private *priv = dev_get_drvdata(dev); + int err; + + err = clk_prepare_enable(priv->clk); + if (err) + return err; if (priv->data->has_cond_reset) { priv->pm_conf.nscr = readl_relaxed(priv->base + RNG_NSCR); @@ -465,6 +475,8 @@ writel_relaxed(reg, priv->base + RNG_CR); } + clk_disable_unprepare(priv->clk); + return 0; } --- linux-xilinx-6.8.0.orig/drivers/char/ppdev.c +++ linux-xilinx-6.8.0/drivers/char/ppdev.c @@ -296,28 +296,35 @@ if (!port) { pr_warn("%s: no associated port!\n", name); rc = -ENXIO; - goto err; + goto err_free_name; } index = ida_alloc(&ida_index, GFP_KERNEL); + if (index < 0) { + pr_warn("%s: failed to get index!\n", name); + rc = index; + goto err_put_port; + } + memset(&ppdev_cb, 0, sizeof(ppdev_cb)); ppdev_cb.irq_func = pp_irq; ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; ppdev_cb.private = pp; pdev = parport_register_dev_model(port, name, &ppdev_cb, index); - parport_put_port(port); if (!pdev) { pr_warn("%s: failed to register device!\n", name); rc = -ENXIO; ida_free(&ida_index, index); - goto err; + goto err_put_port; } pp->pdev = pdev; pp->index = index; dev_dbg(&pdev->dev, "registered pardevice\n"); -err: +err_put_port: + parport_put_port(port); +err_free_name: kfree(name); return rc; } --- linux-xilinx-6.8.0.orig/drivers/char/random.c +++ linux-xilinx-6.8.0/drivers/char/random.c @@ -702,7 +702,7 @@ static void __cold _credit_init_bits(size_t bits) { - static struct execute_work set_ready; + static DECLARE_WORK(set_ready, crng_set_ready); unsigned int new, orig, add; unsigned long flags; @@ -718,8 +718,8 @@ if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { crng_reseed(NULL); /* Sets crng_init to CRNG_READY under base_crng.lock. */ - if (static_key_initialized) - execute_in_process_context(crng_set_ready, &set_ready); + if (static_key_initialized && system_unbound_wq) + queue_work(system_unbound_wq, &set_ready); atomic_notifier_call_chain(&random_ready_notifier, 0, NULL); wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN); @@ -890,8 +890,8 @@ /* * If we were initialized by the cpu or bootloader before jump labels - * are initialized, then we should enable the static branch here, where - * it's guaranteed that jump labels have been initialized. + * or workqueues are initialized, then we should enable the static + * branch here, where it's guaranteed that these have been initialized. */ if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY) crng_set_ready(NULL); --- linux-xilinx-6.8.0.orig/drivers/char/tpm/tpm_tis_core.c +++ linux-xilinx-6.8.0/drivers/char/tpm/tpm_tis_core.c @@ -919,8 +919,6 @@ int rc; u32 int_status; - INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func); - rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL, tis_int_handler, IRQF_ONESHOT | flags, dev_name(&chip->dev), chip); @@ -1022,7 +1020,8 @@ interrupt = 0; tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); - flush_work(&priv->free_irq_work); + if (priv->free_irq_work.func) + flush_work(&priv->free_irq_work); tpm_tis_clkrun_enable(chip, false); @@ -1132,6 +1131,7 @@ priv->phy_ops = phy_ops; priv->locality_count = 0; mutex_init(&priv->locality_count_mutex); + INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func); dev_set_drvdata(&chip->dev, priv); --- linux-xilinx-6.8.0.orig/drivers/char/tpm/tpm_tis_spi_main.c +++ linux-xilinx-6.8.0/drivers/char/tpm/tpm_tis_spi_main.c @@ -37,6 +37,7 @@ #include "tpm_tis_spi.h" #define MAX_SPI_FRAMESIZE 64 +#define SPI_HDRSIZE 4 /* * TCG SPI flow control is documented in section 6.4 of the spec[1]. In short, @@ -247,7 +248,7 @@ int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy, int irq, const struct tpm_tis_phy_ops *phy_ops) { - phy->iobuf = devm_kmalloc(&spi->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL); + phy->iobuf = devm_kmalloc(&spi->dev, SPI_HDRSIZE + MAX_SPI_FRAMESIZE, GFP_KERNEL); if (!phy->iobuf) return -ENOMEM; --- linux-xilinx-6.8.0.orig/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ linux-xilinx-6.8.0/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -639,8 +639,8 @@ dev_set_drvdata(dev, (void *)drvdata); drvdata->base_address = devm_platform_ioremap_resource(pdev, 0); - if (!drvdata->base_address) { - retval = -ENODEV; + if (IS_ERR(drvdata->base_address)) { + retval = PTR_ERR(drvdata->base_address); goto failed; } --- linux-xilinx-6.8.0.orig/drivers/clk/Kconfig +++ linux-xilinx-6.8.0/drivers/clk/Kconfig @@ -170,6 +170,38 @@ help This driver supports the clocks on Bitmain BM1880 SoC. +config COMMON_CLK_SI5324 + tristate "Clock driver for SiLabs 5324 and compatible devices" + depends on I2C + depends on OF + select REGMAP_I2C + help + This driver supports Silicon Labs 5324/5319/5328 programmable + clock generators. Dynamic programming of the oscillator is done + via I2C. + +config COMMON_CLK_IDT8T49N24X + tristate "Clock driver for IDT 8T49N24x" + depends on I2C + depends on OF + select REGMAP_I2C + help + ---help--- + This driver supports the IDT 8T49N24x universal frequency translator + product family. The only chip in the family that is currently + supported is the 8T49N241. The driver supports setting the rate for + all four outputs on the chip and automatically calculating/setting + the appropriate VCO value. + + The driver can read a full register map from the DT, + and will use that register map to initialize the attached part + (via I2C) when the system boots. Any configuration not supported + by the common clock framework must be done via the full register + map, including optimized settings. + + All outputs are currently assumed to be LVDS, unless overridden + in the full register map in the DT. + config COMMON_CLK_CDCE706 tristate "Clock driver for TI CDCE706 clock synthesizer" depends on I2C @@ -466,6 +498,13 @@ Not all features of the PLL are currently supported by the driver. +config COMMON_CLK_PROXO + bool "Clock driver for Renesas ProXO" + depends on I2C && OF + select REGMAP_I2C + help + Support for the Renesas ProXO oscillator clock. + source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" source "drivers/clk/baikal-t1/Kconfig" --- linux-xilinx-6.8.0.orig/drivers/clk/Makefile +++ linux-xilinx-6.8.0/drivers/clk/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o +obj-$(CONFIG_COMMON_CLK_PROXO) += clk-proxo.o obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o @@ -71,6 +72,8 @@ obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o +clk-si5324drv-y := si5324drv.o clk-si5324.o +obj-$(CONFIG_COMMON_CLK_SI5324) += clk-si5324drv.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o obj-$(CONFIG_CLK_TWL) += clk-twl.o obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o @@ -93,6 +96,7 @@ obj-$(CONFIG_ARCH_BERLIN) += berlin/ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ +obj-$(CONFIG_COMMON_CLK_IDT8T49N24X) += idt/ obj-y += imgtec/ obj-y += imx/ obj-y += ingenic/ --- linux-xilinx-6.8.0.orig/drivers/clk/bcm/clk-bcm2711-dvp.c +++ linux-xilinx-6.8.0/drivers/clk/bcm/clk-bcm2711-dvp.c @@ -56,6 +56,8 @@ if (ret) return ret; + data->num = NR_CLOCKS; + data->hws[0] = clk_hw_register_gate_parent_data(&pdev->dev, "hdmi0-108MHz", &clk_dvp_parent, 0, @@ -76,7 +78,6 @@ goto unregister_clk0; } - data->num = NR_CLOCKS; ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get, data); if (ret) --- linux-xilinx-6.8.0.orig/drivers/clk/bcm/clk-raspberrypi.c +++ linux-xilinx-6.8.0/drivers/clk/bcm/clk-raspberrypi.c @@ -371,8 +371,8 @@ if (IS_ERR(hw)) return PTR_ERR(hw); - data->hws[clks->id] = hw; data->num = clks->id + 1; + data->hws[clks->id] = hw; } clks++; --- linux-xilinx-6.8.0.orig/drivers/clk/clk-proxo.c +++ linux-xilinx-6.8.0/drivers/clk/clk-proxo.c @@ -0,0 +1,409 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common clock framework driver for the ProXO family of quartz-based oscillators. + * + * Copyright (c) 2022 Renesas Electronics Corporation + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Most ProXO products have a 50MHz xtal, can be overridden in device tree */ +#define PROXO_DEFAULT_XTAL 50000000 + +/* VCO range is 6.86 GHz to 8.65 GHz */ +#define PROXO_FVCO_MIN 6860000000ULL +#define PROXO_FVCO_MAX 8650000000ULL + +/* Output range is 15MHz to 2.1GHz */ +#define PROXO_FOUT_MIN 15000000UL +#define PROXO_FOUT_MAX 2100000000UL + +#define PROXO_FRAC_BITS 24 +#define PROXO_FRAC_DIVISOR BIT(PROXO_FRAC_BITS) + +/* Disable the doubler if the crystal is > 80MHz */ +#define PROXO_FDBL_MAX 80000000U + +#define PROXO_OUTDIV_MIN 4 +#define PROXO_OUTDIV_MAX 511 +#define PROXO_FB_MIN 41 + +#define PROXO_REG_FREQ0 0x10 +#define PROXO_REG_XO 0x51 +#define PROXO_REG_TRIG 0x62 + +#define OUTDIV_8_MASK 0x80 +#define FBDIV_INT_8_7_MASK 0x30 +#define FBDIV_INT_6_0_MASK 0x7f +#define DOUBLE_DIS_MASK 0x80 +#define CP_MASK 0x0e +#define PLL_MODE_MASK 0x01 + +enum proxo_model { + PROXO_XP, +}; + +enum proxo_pll_mode { + PLL_MODE_FRAC, + PLL_MODE_INT, +}; + +struct clk_proxo { + struct clk_hw hw; + struct regmap *regmap; + struct i2c_client *i2c_client; + enum proxo_model model; + u32 fxtal; + u64 fvco; + u32 fout; + u8 double_dis; + u16 fb_int; + u32 fb_frac; + u16 out_div; +}; + +#define to_clk_proxo(_hw) container_of(_hw, struct clk_proxo, hw) + +static u8 proxo_get_cp_value(u64 fvco) +{ + if (fvco < 7000000000ULL) + return 5; + else if (fvco >= 7000000000ULL && fvco < 7400000000ULL) + return 4; + else if (fvco >= 7400000000ULL && fvco < 7800000000ULL) + return 3; + else + return 2; +} + +static u64 proxo_calc_fvco(u32 fxtal, u8 double_dis, u16 fb_int, u32 fb_frac) +{ + u64 fref, fvco; + u8 doubler; + + doubler = double_dis ? 1 : 2; + fref = (u64)fxtal * doubler; + fvco = (fref * fb_int) + div_u64(fref * fb_frac, PROXO_FRAC_DIVISOR); + + return fvco; +} + +static int proxo_get_divs(struct clk_proxo *proxo, u16 *out_div, u16 *fb_int, u32 *fb_frac, + u8 *double_dis) +{ + int ret; + u8 reg[6]; + unsigned int xo; + + ret = regmap_bulk_read(proxo->regmap, PROXO_REG_FREQ0, reg, ARRAY_SIZE(reg)); + if (ret) + return ret; + + ret = regmap_read(proxo->regmap, PROXO_REG_XO, &xo); + if (ret) + return ret; + + *out_div = (u16_get_bits(reg[1], OUTDIV_8_MASK) << 8) + reg[0]; + *fb_int = (u16_get_bits(reg[2], FBDIV_INT_8_7_MASK) << 7) + (reg[1] & FBDIV_INT_6_0_MASK); + *fb_frac = ((u32)reg[5] << 16) + ((u32)reg[4] << 8) + reg[3]; + *double_dis = !!(xo & DOUBLE_DIS_MASK); + + if (*fb_frac > (PROXO_FRAC_DIVISOR >> 1)) + (*fb_int)--; + + pr_debug("%s - out_div: %u, fb_int: %u, fb_frac: %u, doubler_dis: %u\n", + __func__, *out_div, *fb_int, *fb_frac, *double_dis); + + return ret; +} + +static int proxo_get_defaults(struct clk_proxo *proxo) +{ + int ret; + + ret = proxo_get_divs(proxo, &proxo->out_div, &proxo->fb_int, &proxo->fb_frac, + &proxo->double_dis); + if (ret) + return ret; + + proxo->fvco = proxo_calc_fvco(proxo->fxtal, proxo->double_dis, proxo->fb_int, + proxo->fb_frac); + proxo->fout = div_u64(proxo->fvco, proxo->out_div); + + pr_debug("%s - out_div: %u, fb_int: %u, fb_frac: %u, doubler_dis: %u, fvco: %llu, fout: %u\n", + __func__, proxo->out_div, proxo->fb_int, proxo->fb_frac, proxo->double_dis, + proxo->fvco, proxo->fout); + + return ret; +} + +static int proxo_calc_divs(unsigned long frequency, struct clk_proxo *proxo, u32 *fout, + u16 *out_div, u16 *fb_int, u32 *fb_frac, u8 *double_dis) +{ + int i; + u8 doubler; + u16 out_div_start; + u32 fref; + u64 fvco; + bool found = false, allow_frac = false; + + out_div_start = 1 + div64_u64(PROXO_FVCO_MIN, frequency); + doubler = proxo->fxtal <= PROXO_FDBL_MAX ? 2 : 1; + fref = proxo->fxtal * doubler; + *fout = (u32)max(PROXO_FOUT_MIN, min(PROXO_FOUT_MAX, (unsigned long)*fout)); + *out_div = PROXO_OUTDIV_MIN; + *fb_int = PROXO_FB_MIN; + *fb_frac = 0; + *double_dis = doubler == 1 ? 1 : 0; + +retry: + for (i = out_div_start; i <= PROXO_OUTDIV_MAX; ++i) { + *out_div = i; + fvco = frequency * *out_div; + if (fvco > PROXO_FVCO_MAX) { + allow_frac = true; + goto retry; + } + *fb_int = div_u64_rem(fvco, fref, fb_frac); + if (*fb_frac == 0) { + found = true; + break; + } + if (allow_frac) { + *fb_frac = 1 + (u32)div_u64((u64)*fb_frac << PROXO_FRAC_BITS, fref); + found = true; + break; + } + } + + if (!found) + return -EINVAL; + + if (fvco < PROXO_FVCO_MIN || fvco > PROXO_FVCO_MAX) + return -EINVAL; + + fvco = ((u64)fref * *fb_int) + div_u64((u64)fref * *fb_frac, PROXO_FRAC_DIVISOR); + *fout = div_u64(fvco, *out_div); + + return 0; +} + +static int proxo_update_frequency(struct clk_proxo *proxo) +{ + enum proxo_pll_mode pll_mode; + u8 cp_value; + u16 fb_int; + u8 reg[6]; + + cp_value = proxo_get_cp_value(proxo->fvco); + pll_mode = proxo->fb_frac == 0 ? PLL_MODE_INT : PLL_MODE_FRAC; + fb_int = proxo->fb_frac > (PROXO_FRAC_DIVISOR >> 1) ? proxo->fb_int + 1 : proxo->fb_int; + + reg[0] = proxo->out_div & 0xff; + reg[1] = ((proxo->out_div >> 1) & OUTDIV_8_MASK) + (fb_int & FBDIV_INT_6_0_MASK); + reg[2] = (fb_int >> 3) & FBDIV_INT_8_7_MASK; + reg[2] = u8_replace_bits(reg[2], cp_value, CP_MASK); + reg[2] = u8_replace_bits(reg[2], pll_mode, PLL_MODE_MASK); + reg[3] = proxo->fb_frac & 0xff; + reg[4] = (proxo->fb_frac >> 8) & 0xff; + reg[5] = (proxo->fb_frac >> 16) & 0xff; + + return regmap_bulk_write(proxo->regmap, PROXO_REG_FREQ0, reg, ARRAY_SIZE(reg)); +} + +static int proxo_set_frequency(struct clk_proxo *proxo, unsigned long frequency) +{ + int ret; + + ret = proxo_calc_divs(frequency, proxo, &proxo->fout, &proxo->out_div, &proxo->fb_int, + &proxo->fb_frac, &proxo->double_dis); + if (ret) + return ret; + + proxo->fvco = proxo_calc_fvco(proxo->fxtal, proxo->double_dis, proxo->fb_int, + proxo->fb_frac); + proxo->fout = div_u64(proxo->fvco, proxo->out_div); + + pr_debug("%s - out_div: %u, fb_int: %u, fb_frac: %u, doubler_dis: %u, fvco: %llu, fout: %u\n", + __func__, proxo->out_div, proxo->fb_int, proxo->fb_frac, + proxo->double_dis, proxo->fvco, proxo->fout); + + proxo_update_frequency(proxo); + + /* trigger frequency change */ + regmap_write(proxo->regmap, PROXO_REG_TRIG, 0x00); + regmap_write(proxo->regmap, PROXO_REG_TRIG, 0x01); + regmap_write(proxo->regmap, PROXO_REG_TRIG, 0x00); + + return ret; +} + +static unsigned long proxo_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_proxo *proxo = to_clk_proxo(hw); + int ret; + u8 double_dis; + u16 out_div, fb_int; + u32 fout, fb_frac; + u64 fvco; + + ret = proxo_get_divs(proxo, &out_div, &fb_int, &fb_frac, &double_dis); + if (ret) { + dev_err(&proxo->i2c_client->dev, "unable to recalc rate\n"); + return 0; + } + + fvco = proxo_calc_fvco(proxo->fxtal, double_dis, fb_int, fb_frac); + fout = div_u64(fvco, out_div); + + return fout; +} + +static long proxo_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) +{ + struct clk_proxo *proxo = to_clk_proxo(hw); + int ret; + u8 double_dis; + u16 out_div, fb_int; + u32 fout, fb_frac; + + if (!rate) + return 0; + + ret = proxo_calc_divs(rate, proxo, &fout, &out_div, &fb_int, &fb_frac, &double_dis); + if (ret) { + dev_err(&proxo->i2c_client->dev, "unable to round rate\n"); + return 0; + } + + return fout; +} + +static int proxo_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) +{ + struct clk_proxo *proxo = to_clk_proxo(hw); + + if (rate < PROXO_FOUT_MIN || rate > PROXO_FOUT_MAX) { + dev_err(&proxo->i2c_client->dev, "requested frequency %lu Hz is out of range\n", + rate); + return -EINVAL; + } + + return proxo_set_frequency(proxo, rate); +} + +static const struct clk_ops proxo_clk_ops = { + .recalc_rate = proxo_recalc_rate, + .round_rate = proxo_round_rate, + .set_rate = proxo_set_rate, +}; + +static const struct i2c_device_id proxo_i2c_id[] = { + { "proxo-xp", PROXO_XP }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, proxo_i2c_id); + +static const struct regmap_config proxo_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x63, + .cache_type = REGCACHE_RBTREE, + .use_single_write = true, + .use_single_read = true, +}; + +static int proxo_probe(struct i2c_client *client) +{ + struct clk_proxo *proxo; + struct clk_init_data init; + const struct i2c_device_id *id = i2c_match_id(proxo_i2c_id, client); + int ret; + + proxo = devm_kzalloc(&client->dev, sizeof(*proxo), GFP_KERNEL); + if (!proxo) + return -ENOMEM; + + init.ops = &proxo_clk_ops; + init.flags = 0; + init.num_parents = 0; + proxo->hw.init = &init; + proxo->i2c_client = client; + proxo->model = id->driver_data; + + if (of_property_read_string(client->dev.of_node, "clock-output-names", &init.name)) + init.name = client->dev.of_node->name; + + if (of_property_read_u32(client->dev.of_node, "renesas,crystal-frequency", &proxo->fxtal)) + proxo->fxtal = PROXO_DEFAULT_XTAL; + + proxo->regmap = devm_regmap_init_i2c(client, &proxo_regmap_config); + if (IS_ERR(proxo->regmap)) + return PTR_ERR(proxo->regmap); + + i2c_set_clientdata(client, proxo); + + ret = proxo_get_defaults(proxo); + if (ret) { + dev_err(&client->dev, "getting defaults failed\n"); + return ret; + } + + ret = devm_clk_hw_register(&client->dev, &proxo->hw); + if (ret) { + dev_err(&client->dev, "clock registration failed\n"); + return ret; + } + + ret = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get, &proxo->hw); + if (ret) { + dev_err(&client->dev, "unable to add clk provider\n"); + return ret; + } + + ret = clk_set_rate_range(proxo->hw.clk, PROXO_FOUT_MIN, PROXO_FOUT_MAX); + if (ret) { + dev_err(&client->dev, "clk_set_rate_range failed\n"); + return ret; + } + + dev_info(&client->dev, "registered, current frequency %u Hz\n", proxo->fout); + + return ret; +} + +static void proxo_remove(struct i2c_client *client) +{ + of_clk_del_provider(client->dev.of_node); +} + +static const struct of_device_id proxo_of_match[] = { + { .compatible = "renesas,proxo-xp" }, + {}, +}; +MODULE_DEVICE_TABLE(of, proxo_of_match); + +static struct i2c_driver proxo_i2c_driver = { + .driver = { + .name = "proxo", + .of_match_table = proxo_of_match, + }, + .probe = proxo_probe, + .remove = proxo_remove, + .id_table = proxo_i2c_id, +}; +module_i2c_driver(proxo_i2c_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alex Helms pll_amplitude = RS9_REG_SS_AMP_0V7; - rs9->pll_ssc = RS9_REG_SS_SSC_100; + rs9->pll_amplitude = RS9_REG_SS_AMP_DEFAULT; + rs9->pll_ssc = RS9_REG_SS_SSC_DEFAULT; /* Output clock amplitude */ ret = of_property_read_u32(np, "renesas,out-amplitude-microvolt", @@ -247,13 +249,13 @@ int i; /* If amplitude is non-default, update it. */ - if (rs9->pll_amplitude != RS9_REG_SS_AMP_0V7) { + if (rs9->pll_amplitude != RS9_REG_SS_AMP_DEFAULT) { regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_AMP_MASK, rs9->pll_amplitude); } /* If SSC is non-default, update it. */ - if (rs9->pll_ssc != RS9_REG_SS_SSC_100) { + if (rs9->pll_ssc != RS9_REG_SS_SSC_DEFAULT) { regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_SSC_MASK, rs9->pll_ssc); } --- linux-xilinx-6.8.0.orig/drivers/clk/clk-si5324.c +++ linux-xilinx-6.8.0/drivers/clk/clk-si5324.c @@ -0,0 +1,1239 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * clk-si5324.c - Si5324 clock driver + * + * Copyright (C) 2017-2018 Xilinx, Inc. + * + * Author: Venkateshwar Rao G + * Leon Woestenberg + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk-si5324.h" +#include "si5324.h" +#include "si5324drv.h" + +struct si5324_driver_data; + +/** + * struct si5324_parameters - si5324 core parameters + * + * @n1_hs_min: Minimum high-speed n1 output divider + * @n1_hs_max: Maximum high-speed n1 output divider + * @n1_hs: n1 high-speed output divider + * @nc1_ls_min: Minimum low-speed clkout1 output divider + * @nc1_ls_max: Maximum low-speed clkout1 output divider + * @nc1_ls: Clkout1 low-speed output divider + * @nc2_ls_min: Minimum low-speed clkout2 output divider + * @nc2_ls_max: Maximum low-speed clkout2 output divider + * @nc2_ls: Clkout2 low-speed output divider + * @n2_hs: High-speed feedback divider + * @n2_ls_min: Minimum low-speed feedback divider + * @n2_ls_max: Maximum low-speed feedback divider + * @n2_ls: Low-speed feedback divider + * @n31_min: Minimum input divider for clk1 + * @n31_max: Maximum input divider for clk1 + * @n31: Input divider for clk1 + * @n32_min: Minimum input divider for clk2 + * @n32_max: Maximum input divider for clk2 + * @n32: Input divider for clk2 + * @fin: Input frequency + * @fout: Output frequency + * @fosc: Osc frequency + * @best_delta_fout: Delta out frequency + * @best_fout: Best output frequency + * @best_n1_hs: Best high speed output divider + * @best_nc1_ls: Best low speed clkout1 divider + * @best_n2_hs: Best high speed feedback divider + * @best_n2_ls: Best low speed feedback divider + * @best_n3: Best input clock divider + * @valid: Validility + */ +struct si5324_parameters { + u32 n1_hs_min; + u32 n1_hs_max; + u32 n1_hs; + u32 nc1_ls_min; + u32 nc1_ls_max; + u32 nc1_ls; + u32 nc2_ls_min; + u32 nc2_ls_max; + u32 nc2_ls; + u32 n2_hs; + u32 n2_ls_min; + u32 n2_ls_max; + u32 n2_ls; + u32 n31_min; + u32 n31_max; + u32 n31; + u32 n32_min; + u32 n32_max; + u32 n32; + u64 fin; + u64 fout; + u64 fosc; + u64 best_delta_fout; + u64 best_fout; + u32 best_n1_hs; + u32 best_nc1_ls; + u32 best_n2_hs; + u32 best_n2_ls; + u32 best_n3; + int valid; +}; + +/** + * struct si5324_hw_data - Clock parameters + * + * @hw: Handle between common and hardware-specific interfaces + * @drvdata: Driver private data + * @num: Differential pair clock number + */ +struct si5324_hw_data { + struct clk_hw hw; + struct si5324_driver_data *drvdata; + unsigned char num; +}; + +/** + * struct si5324_driver_data - Driver parameters + * @client: I2C client pointer + * @regmap: Device's regmap + * @onecell: Clock onecell data + * @params: Device parameters + * @pxtal: Clock + * @pxtal_name: Clock name + * @xtal: Reference clock + * @pclkin1: Clock in 1 + * @pclkin1_name: Clock in 1 name + * @clkin1: Differential input clock 1 + * @pclkin2: Clock in 2 + * @pclkin2_name: Clock in 2 name + * @clkin2: Differential input clock 2 + * @pll: Pll clock + * @clkout: Output clock + * @rate_clkout0: Clock out 0 rate + * @rate_clkout1: Clock out 1 rate + */ +struct si5324_driver_data { + struct i2c_client *client; + struct regmap *regmap; + struct clk_onecell_data onecell; + struct si5324_parameters params; + struct clk *pxtal; + const char *pxtal_name; + struct clk_hw xtal; + struct clk *pclkin1; + const char *pclkin1_name; + struct clk_hw clkin1; + struct clk *pclkin2; + const char *pclkin2_name; + struct clk_hw clkin2; + struct si5324_hw_data pll; + struct si5324_hw_data *clkout; + unsigned long rate_clkout0; + unsigned long rate_clkout1; +}; + +static const char * const si5324_input_names[] = { + "xtal", "clkin1", "clkin2" +}; + +static const char * const si5324_pll_name = "pll"; + +static const char * const si5324_clkout_names[] = { + "clk0", "clk1" +}; + +enum si53xx_variant { + si5319, + si5324, + si5328 +}; + +static const char * const si53xx_variant_name[] = { + "si5319", "si5324", "si5328" +}; + +/** + * si5324_reg_read - Read a single si5324 register. + * + * @drvdata: Device to read from. + * @reg: Register to read. + * + * This function reads data from a single register + * + * Return: Data of the register on success, error number on failure + */ +static inline int +si5324_reg_read(struct si5324_driver_data *drvdata, u8 reg) +{ + u32 val; + int ret; + + ret = regmap_read(drvdata->regmap, reg, &val); + if (ret < 0) { + dev_err(&drvdata->client->dev, + "unable to read from reg%02x\n", reg); + return ret; + } + + return (u8)val; +} + +/** + * si5324_bulk_read - Read multiple si5324 registers + * + * @drvdata: Device to read from + * @reg: First register to be read from + * @count: Number of registers + * @buf: Pointer to store read value + * + * This function reads from multiple registers which are in + * sequential order + * + * Return: Number of bytes read + */ +static inline int si5324_bulk_read(struct si5324_driver_data *drvdata, + u8 reg, u8 count, u8 *buf) +{ + return regmap_bulk_read(drvdata->regmap, reg, buf, count); +} + +/** + * si5324_reg_write - Write a single si5324 register. + * + * @drvdata: Device to write to. + * @reg: Register to write to. + * @val: Value to write. + * + * This function writes into a single register + * + * Return: Zero on success, a negative error number on failure. + * + */ +static inline int si5324_reg_write(struct si5324_driver_data *drvdata, + u8 reg, u8 val) +{ + int ret = regmap_write(drvdata->regmap, reg, val); + + dev_dbg(&drvdata->client->dev, "%s 0x%02x @%02d\n", __func__, + (int)val, (int)reg); + return ret; +} + +/** + * si5324_bulk_write - Write into multiple si5324 registers + * + * @drvdata: Device to write to + * @reg: First register + * @count: Number of registers + * @buf: Block of data to be written + * + * This function writes into multiple registers. + * + * Return: Zero on success, a negative error number on failure. + */ +static inline int si5324_bulk_write(struct si5324_driver_data *drvdata, + u8 reg, u8 count, const u8 *buf) +{ + return regmap_raw_write(drvdata->regmap, reg, buf, count); +} + +/** + * si5324_set_bits - Set the value of a bitfield in a si5324 register + * + * @drvdata: Device to write to. + * @reg: Register to write to. + * @mask: Mask of bits to set. + * @val: Value to set (unshifted) + * + * This function set particular bits in register + * + * Return: Zero on success, a negative error number on failure. + */ +static inline int si5324_set_bits(struct si5324_driver_data *drvdata, + u8 reg, u8 mask, u8 val) +{ + return regmap_update_bits(drvdata->regmap, reg, mask, val); +} + +/** + * si5324_bulk_scatter_write - Write into multiple si5324 registers + * + * @drvdata: Device to write to + * @count: Number of registers + * @buf: Register and data to write + * + * This function writes into multiple registers which are need not + * to be in sequential order. + * + * Return: Number of bytes written + */ +static inline int +si5324_bulk_scatter_write(struct si5324_driver_data *drvdata, + u8 count, const u8 *buf) +{ + int i; + int ret = 0; + + for (i = 0; i < count; i++) { + ret = si5324_reg_write(drvdata, buf[i * 2], buf[i * 2 + 1]); + if (ret) + return ret; + } + return ret; +} + +/** + * si5324_initialize - Initializes si5324 device + * + * @drvdata: Device instance + * + * This function initializes si5324 with the following settings + * Keep reset asserted for 20ms + * 1. freerun mode + * 2. Disable output clocks during calibration + * 3. Clock selection mode : default value, manual + * 4. output signal format : LVDS for clkout1, disable clkout2 + * 5. CS_CA pin in ignored + * 6. Set lock time to 13.3ms + * 7. Enables the fastlock. + * + * Return: Zero on success, negative number on failure. + */ +static int si5324_initialize(struct si5324_driver_data *drvdata) +{ + int ret = 0; + + si5324_set_bits(drvdata, SI5324_RESET_CALIB, + SI5324_RST_ALL, SI5324_RST_ALL); + msleep(SI5324_RESET_DELAY_MS); + si5324_set_bits(drvdata, SI5324_RESET_CALIB, SI5324_RST_ALL, 0); + msleep(SI5324_RESET_DELAY_MS); + + ret = si5324_reg_read(drvdata, SI5324_CONTROL); + if (ret < 0) + return ret; + + si5324_reg_write(drvdata, SI5324_CONTROL, + (ret | SI5324_CONTROL_FREE_RUN)); + + ret = si5324_reg_read(drvdata, SI5324_CKSEL); + if (ret < 0) + return ret; + + si5324_reg_write(drvdata, SI5324_CKSEL, (ret | SI5324_CKSEL_SQL_ICAL)); + si5324_reg_write(drvdata, SI3324_AUTOSEL, SI5324_AUTOSEL_DEF); + si5324_reg_write(drvdata, SI5324_OUTPUT_SIGFMT, + SI5324_OUTPUT_SF1_DEFAULT); + + ret = si5324_reg_read(drvdata, SI5324_DSBL_CLKOUT); + if (ret < 0) + return ret; + + si5324_reg_write(drvdata, SI5324_DSBL_CLKOUT, + (ret | SI5324_DSBL_CLKOUT2)); + ret = si5324_reg_read(drvdata, SI5324_POWERDOWN); + if (ret < 0) + return ret; + + si5324_reg_write(drvdata, SI5324_POWERDOWN, (ret | SI5324_PD_CK2)); + si5324_reg_write(drvdata, SI5324_FOS_LOCKT, SI5324_FOS_DEFAULT); + + ret = si5324_reg_read(drvdata, SI5324_CK_ACTV_SEL); + if (ret < 0) + return ret; + + si5324_reg_write(drvdata, SI5324_CK_ACTV_SEL, SI5324_CK_DEFAULT); + ret = si5324_reg_read(drvdata, SI5324_FASTLOCK); + if (ret < 0) + return ret; + + si5324_reg_write(drvdata, SI5324_FASTLOCK, (ret | SI5324_FASTLOCK_EN)); + return 0; +} + +/** + * si5324_read_parameters - Reads clock divider parameters + * + * @drvdata: Device to read from + * + * This function reads the clock divider parameters into driver structure. + * + * Following table gives the buffer index, register number and + * register name with bit fields + * 0 25 N1_HS[2:0] + * 6 31 NC1_LS[19:16] + * 7 32 NC1_LS[15:8] + * 8 33 NC1_LS[7:0] + * 9 34 NC2_LS[19:16] + * 10 35 NC2_LS[15:8] + * 11 36 NC2_LS[7:0] + * 15 40 N2_HS[2:0] N2_LS[19:16] + * 16 41 N2_LS[15:8] + * 17 42 N2_LS[7:0] + * 18 43 N31[18:16] + * 19 44 N31[15:8] + * 20 45 N31[7:0] + * 21 46 N32[18:16] + * 22 47 N32[15:8] + * 23 48 N32[7:0] + */ +static void si5324_read_parameters(struct si5324_driver_data *drvdata) +{ + u8 buf[SI5324_PARAM_LEN]; + + si5324_bulk_read(drvdata, SI5324_N1_HS, SI5324_N1_PARAM_LEN, &buf[0]); + si5324_bulk_read(drvdata, SI5324_NC1_LS_H, SI5324_NC_PARAM_LEN, + &buf[6]); + si5324_bulk_read(drvdata, SI5324_N2_HS_LS_H, SI5324_N2_PARAM_LEN, + &buf[15]); + + drvdata->params.n1_hs = (buf[0] >> SI5324_N1_HS_VAL_SHIFT); + drvdata->params.n1_hs += 4; + + drvdata->params.nc1_ls = ((buf[6] & SI5324_DIV_LS_MASK) << + SI5324_HSHIFT) | (buf[7] << SI5324_LSHIFT) | + buf[8]; + drvdata->params.nc1_ls += 1; + drvdata->params.nc2_ls = ((buf[9] & SI5324_DIV_LS_MASK) << + SI5324_HSHIFT) | (buf[10] << SI5324_LSHIFT) | + buf[11]; + drvdata->params.nc2_ls += 1; + drvdata->params.n2_ls = ((buf[15] & SI5324_DIV_LS_MASK) << + SI5324_HSHIFT) | (buf[16] << SI5324_LSHIFT) | + buf[17]; + drvdata->params.n2_ls += 1; + drvdata->params.n2_hs = buf[15] >> SI5324_N2_HS_LS_H_VAL_SHIFT; + drvdata->params.n2_hs += 4; + drvdata->params.n31 = ((buf[18] & SI5324_DIV_LS_MASK) << + SI5324_HSHIFT) | (buf[19] << SI5324_LSHIFT) | + buf[20]; + drvdata->params.n31 += 1; + drvdata->params.n32 = ((buf[21] & SI5324_DIV_LS_MASK) << + SI5324_HSHIFT) | (buf[22] << SI5324_LSHIFT) | + buf[23]; + drvdata->params.n32 += 1; + drvdata->params.valid = 1; +} + +static bool si5324_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + return true; +} + +/** + * si5324_regmap_is_readable - Checks the register is readable or not + * + * @dev: Registered device + * @reg: Register offset + * + * Checks the register is readable or not. + * + * Return: True if the register is reabdle, False if it is not readable. + */ +static bool si5324_regmap_is_readable(struct device *dev, unsigned int reg) +{ + if ((reg > SI5324_POWERDOWN && reg < SI5324_FOS_LOCKT) || + (reg > SI5324_N1_HS && reg < SI5324_NC1_LS_H) || + (reg > SI5324_NC2_LS_L && reg < SI5324_N2_HS_LS_H) || + (reg > SI5324_N32_CLKIN_L && reg < SI5324_FOS_CLKIN_RATE) || + (reg > SI5324_FOS_CLKIN_RATE && reg < SI5324_PLL_ACTV_CLK) || + reg > SI5324_SKEW2) + return false; + + return true; +} + +/** + * si5324_regmap_is_writeable - Checks the register is writable or not + * + * @dev: Registered device + * @reg: Register offset + * + * Checks the register is writable or not. + * + * Return: True if the register is writeable, False if it's not writeable. + */ +static bool si5324_regmap_is_writeable(struct device *dev, unsigned int reg) +{ + if ((reg > SI5324_POWERDOWN && reg < SI5324_FOS_LOCKT) || + (reg > SI5324_N1_HS && reg < SI5324_NC1_LS_H) || + (reg > SI5324_NC2_LS_L && reg < SI5324_N2_HS_LS_H) || + (reg > SI5324_N32_CLKIN_L && reg < SI5324_FOS_CLKIN_RATE) || + (reg > SI5324_FOS_CLKIN_RATE && reg < SI5324_PLL_ACTV_CLK) || + reg > SI5324_SKEW2 || + (reg >= SI5324_PLL_ACTV_CLK && reg <= SI5324_CLKIN_LOL_STATUS) || + (reg >= SI5324_PARTNO_H && reg <= SI5324_PARTNO_L)) + return false; + + return true; +} + +static const struct regmap_config si5324_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .max_register = 144, + .writeable_reg = si5324_regmap_is_writeable, + .readable_reg = si5324_regmap_is_readable, + .volatile_reg = si5324_regmap_is_volatile, +}; + +static int si5324_xtal_prepare(struct clk_hw *hw) +{ + return 0; +} + +static void si5324_xtal_unprepare(struct clk_hw *hw) +{ +} + +static const struct clk_ops si5324_xtal_ops = { + .prepare = si5324_xtal_prepare, + .unprepare = si5324_xtal_unprepare, +}; + +/** + * si5324_clkin_prepare - Prepare the clkin + * + * @hw: Handle between common and hardware-specific interfaces + * + * This function enables the particular clk + * + * Return: Zero on success, a negative error number on failure. + */ +static int si5324_clkin_prepare(struct clk_hw *hw) +{ + int ret = 0; + struct si5324_driver_data *drvdata; + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + + if (hwdata->num == SI5324_CLKIN1) { + drvdata = container_of(hw, struct si5324_driver_data, clkin1); + ret = si5324_set_bits(drvdata, SI5324_CONTROL, + SI5324_CONTROL_FREE_RUN, 0); + ret = si5324_set_bits(drvdata, SI5324_POWERDOWN, SI5324_PD_CK1 | + SI5324_PD_CK2, SI5324_PD_CK2); + } else if (hwdata->num == SI5324_CLKIN2) { + drvdata = container_of(hw, struct si5324_driver_data, clkin2); + ret = si5324_set_bits(drvdata, SI5324_CONTROL, + SI5324_CONTROL_FREE_RUN, 0); + ret = si5324_set_bits(drvdata, SI5324_POWERDOWN, SI5324_PD_CK1 | + SI5324_PD_CK2, SI5324_PD_CK1); + } + + return ret; +} + +/** + * si5324_clkin_unprepare - Unprepare the clkin + * + * @hw: Clock hardware + * + * This function enables the particular clk. + */ +static void si5324_clkin_unprepare(struct clk_hw *hw) +{ + struct si5324_driver_data *drvdata; + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + + if (hwdata->num == SI5324_CLKIN1) { + drvdata = container_of(hw, struct si5324_driver_data, clkin1); + si5324_set_bits(drvdata, SI5324_POWERDOWN, + SI5324_PD_CK1 | SI5324_PD_CK2, SI5324_PD_CK1); + } else if (hwdata->num == SI5324_CLKIN2) { + drvdata = container_of(hw, struct si5324_driver_data, clkin2); + si5324_set_bits(drvdata, SI5324_POWERDOWN, + SI5324_PD_CK1 | SI5324_PD_CK2, SI5324_PD_CK1); + } +} + +static unsigned long si5324_clkin_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return 0; +} + +static const struct clk_ops si5324_clkin_ops = { + .prepare = si5324_clkin_prepare, + .unprepare = si5324_clkin_unprepare, + .recalc_rate = si5324_clkin_recalc_rate, +}; + +static int si5324_pll_reparent(struct si5324_driver_data *drvdata, + int num, enum si5324_pll_src parent) +{ + if (parent == SI5324_PLL_SRC_XTAL) { + si5324_set_bits(drvdata, SI5324_CONTROL, + SI5324_CONTROL_FREE_RUN, + SI5324_CONTROL_FREE_RUN); + si5324_set_bits(drvdata, SI5324_POWERDOWN, + SI5324_PD_CK1 | SI5324_PD_CK2, SI5324_PD_CK1); + si5324_set_bits(drvdata, SI5324_CKSEL, + SI5324_CK_SEL << SI5324_CKSEL_SHIFT, + 1 << SI5324_CKSEL_SHIFT); + } else if (parent == SI5324_PLL_SRC_CLKIN1) { + si5324_set_bits(drvdata, SI5324_CONTROL, + SI5324_CONTROL_FREE_RUN, 0); + si5324_set_bits(drvdata, SI5324_POWERDOWN, + SI5324_PD_CK1 | SI5324_PD_CK2, SI5324_PD_CK2); + si5324_set_bits(drvdata, SI5324_CKSEL, + SI5324_CK_SEL << SI5324_CKSEL_SHIFT, 0); + } else if (parent == SI5324_PLL_SRC_CLKIN2) { + si5324_set_bits(drvdata, SI5324_CONTROL, + SI5324_CONTROL_FREE_RUN, 0); + si5324_set_bits(drvdata, SI5324_POWERDOWN, + SI5324_PD_CK1 | SI5324_PD_CK2, SI5324_PD_CK1); + si5324_set_bits(drvdata, SI5324_CKSEL, + SI5324_CK_SEL << SI5324_CKSEL_SHIFT, + 1 << SI5324_CKSEL_SHIFT); + } + + return 0; +} + +static unsigned char si5324_pll_get_parent(struct clk_hw *hw) +{ + return 0; +} + +/** + * si5324_pll_set_parent - Set parent of clock + * + * @hw: Handle between common and hardware-specific interfaces + * @index: Parent index + * + * This function sets the paraent of clock. + * + * Return: 0 on success, negative error number on failure + */ +static int si5324_pll_set_parent(struct clk_hw *hw, u8 index) +{ + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + enum si5324_pll_src parent; + + if (index == SI5324_SRC_XTAL) + parent = SI5324_PLL_SRC_XTAL; + else if (index == SI5324_SRC_CLKIN1) + parent = SI5324_PLL_SRC_CLKIN1; + else if (index == SI5324_SRC_CLKIN2) + parent = SI5324_PLL_SRC_CLKIN2; + else + return -EINVAL; + + return si5324_pll_reparent(hwdata->drvdata, hwdata->num, parent); +} + +/** + * si5324_pll_recalc_rate - Recalculate clock frequency + * + * @hw: Handle between common and hardware-specific interfaces + * @parent_rate: Clock frequency of parent clock + * + * This function recalculate clock frequency. + * + * Return: Current clock frequency + */ +static unsigned long si5324_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long rate; + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + + if (!hwdata->drvdata->params.valid) + si5324_read_parameters(hwdata->drvdata); + WARN_ON(!hwdata->drvdata->params.valid); + + rate = parent_rate * hwdata->drvdata->params.n2_ls * + hwdata->drvdata->params.n2_hs; + + dev_dbg(&hwdata->drvdata->client->dev, + "%s - %s: n2_ls = %u, n2_hs = %u, parent_rate = %lu, rate = %lu\n", + __func__, clk_hw_get_name(hw), + hwdata->drvdata->params.n2_ls, hwdata->drvdata->params.n2_hs, + parent_rate, (unsigned long)rate); + + return rate; +} + +static long si5324_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + return rate; +} + +static int si5324_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return 0; +} + +static int si5324_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + + dev_err(&hwdata->drvdata->client->dev, + "%s: Missing implementation\n", clk_hw_get_name(hw)); + + return clk_hw_determine_rate_no_reparent(hw, req); +} + +static const struct clk_ops si5324_pll_ops = { + .set_parent = si5324_pll_set_parent, + .get_parent = si5324_pll_get_parent, + .recalc_rate = si5324_pll_recalc_rate, + .round_rate = si5324_pll_round_rate, + .set_rate = si5324_pll_set_rate, + .determine_rate = si5324_determine_rate, +}; + +static int si5324_clkout_set_drive_strength( + struct si5324_driver_data *drvdata, int num, + enum si5324_drive_strength drive) +{ + return 0; +} + +static int si5324_clkout_prepare(struct clk_hw *hw) +{ + return 0; +} + +static void si5324_clkout_unprepare(struct clk_hw *hw) +{ +} + +static unsigned long si5324_clkout_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + unsigned long rate; + + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + + rate = hwdata->drvdata->rate_clkout0; + + return rate; +} + +/** + * si5324_clkout_round_rate - selects the closest value to requested one. + * + * @hw: Handle between common and hardware-specific interfaces + * @rate: Clock rate + * @parent_rate: Parent clock rate + * + * This function selects the rate closest to the requested one. + * + * Return: Clock rate on success, negative error number on failure + */ +static long si5324_clkout_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + u32 ncn_ls, n2_ls, n3n, actual_rate; + u8 n1_hs, n2_hs, bwsel; + int ret; + + ret = si5324_calcfreqsettings(SI5324_REF_CLOCK, rate, &actual_rate, + &n1_hs, &ncn_ls, &n2_hs, &n2_ls, &n3n, + &bwsel); + if (ret < 0) + return ret; + + return actual_rate; +} + +static int si5324_clkout_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct si5324_hw_data *hwdata = + container_of(hw, struct si5324_hw_data, hw); + + u32 ncn_ls, n2_ls, n3n, actual_rate; + u8 n1_hs, n2_hs, bwsel, buf[SI5324_OUT_REGS * 2]; + int i, ret, rc; + + ret = si5324_calcfreqsettings(SI5324_REF_CLOCK, rate, &actual_rate, + &n1_hs, &ncn_ls, &n2_hs, &n2_ls, &n3n, + &bwsel); + if (ret < 0) + return ret; + + hwdata->drvdata->rate_clkout0 = rate; + i = 0; + + /* Enable Free running mode */ + buf[i] = SI5324_CONTROL; + buf[i + 1] = SI5324_FREE_RUN_EN; + i += 2; + + /* Loop bandwidth */ + buf[i] = SI5324_BWSEL; + buf[i + 1] = (bwsel << SI5324_BWSEL_SHIFT) | SI5324_BWSEL_DEF_VAL; + i += 2; + + /* Enable reference clock 2 in free running mode */ + buf[i] = SI5324_POWERDOWN; + /* Enable input clock 2, Disable input clock 1 */ + buf[i + 1] = SI5324_PD_CK1_DIS; + i += 2; + + /* N1_HS */ + buf[i] = SI5324_N1_HS; + buf[i + 1] = n1_hs << SI5324_N1_HS_VAL_SHIFT; + i += 2; + + /* NC1_LS */ + buf[i] = SI5324_NC1_LS_H; + buf[i + 1] = (u8)((ncn_ls & 0x000F0000) >> 16); + buf[i + 2] = SI5324_NC1_LS_M; + buf[i + 3] = (u8)((ncn_ls & 0x0000FF00) >> 8); + buf[i + 4] = SI5324_NC1_LS_L; + buf[i + 5] = (u8)(ncn_ls & 0x000000FF); + i += 6; + + /* N2_HS and N2_LS */ + buf[i] = SI5324_N2_HS_LS_H; + buf[i + 1] = (n2_hs << SI5324_N2_HS_LS_H_VAL_SHIFT); + buf[i + 1] |= (u8)((n2_ls & 0x000F0000) >> 16); + buf[i + 2] = SI5324_N2_LS_H; + buf[i + 3] = (u8)((n2_ls & 0x0000FF00) >> 8); + buf[i + 4] = SI5324_N2_LS_L; + buf[i + 5] = (u8)(n2_ls & 0x000000FF); + i += 6; + + /* N32 (CLKIN2 or XTAL in FREERUNNING mode) */ + buf[i] = SI5324_N32_CLKIN_H; + buf[i + 2] = SI5324_N32_CLKIN_M; + buf[i + 4] = SI5324_N32_CLKIN_L; + buf[i + 1] = (u8)((n3n & 0x00070000) >> 16); + buf[i + 3] = (u8)((n3n & 0x0000FF00) >> 8); + buf[i + 5] = (u8)(n3n & 0x000000FF); + i += 6; + + /* Start calibration */ + buf[i] = SI5324_RESET_CALIB; + buf[i + 1] = SI5324_CALIB_EN; + i += 2; + + hwdata->drvdata->params.valid = 0; + rc = si5324_bulk_scatter_write(hwdata->drvdata, SI5324_OUT_REGS, buf); + + return rc; +} + +static const struct clk_ops si5324_clkout_ops = { + .prepare = si5324_clkout_prepare, + .unprepare = si5324_clkout_unprepare, + .recalc_rate = si5324_clkout_recalc_rate, + .round_rate = si5324_clkout_round_rate, + .set_rate = si5324_clkout_set_rate, +}; + +static const struct of_device_id si5324_dt_ids[] = { + { .compatible = "silabs,si5319" }, + { .compatible = "silabs,si5324" }, + { .compatible = "silabs,si5328" }, + { } +}; +MODULE_DEVICE_TABLE(of, si5324_dt_ids); + +static int si5324_dt_parse(struct i2c_client *client) +{ + struct device_node *child, *np = client->dev.of_node; + struct si5324_platform_data *pdata; + struct property *prop; + const __be32 *p; + int num = 0; + u32 val; + + if (!np) + return 0; + + pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + /* + * property silabs,pll-source : , [<..>] + * allow to selectively set pll source + */ + of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) { + if (num >= 1) { + dev_err(&client->dev, + "invalid pll %d on pll-source prop\n", num); + return -EINVAL; + } + p = of_prop_next_u32(prop, p, &val); + if (!p) { + dev_err(&client->dev, + "missing pll-source for pll %d\n", num); + return -EINVAL; + } + + switch (val) { + case 0: + dev_dbg(&client->dev, "using xtal as parent for pll\n"); + pdata->pll_src = SI5324_PLL_SRC_XTAL; + break; + case 1: + dev_dbg(&client->dev, + "using clkin1 as parent for pll\n"); + pdata->pll_src = SI5324_PLL_SRC_CLKIN1; + break; + case 2: + dev_dbg(&client->dev, + "using clkin2 as parent for pll\n"); + pdata->pll_src = SI5324_PLL_SRC_CLKIN2; + break; + default: + dev_err(&client->dev, + "invalid parent %d for pll %d\n", val, num); + return -EINVAL; + } + } + /* per clkout properties */ + for_each_child_of_node(np, child) { + if (of_property_read_u32(child, "reg", &num)) { + dev_err(&client->dev, "missing reg property of %s\n", + child->name); + goto put_child; + } + + if (num >= 2) { + dev_err(&client->dev, "invalid clkout %d\n", num); + goto put_child; + } + + if (!of_property_read_u32(child, "silabs,drive-strength", + &val)) { + switch (val) { + case SI5324_DRIVE_2MA: + case SI5324_DRIVE_4MA: + case SI5324_DRIVE_6MA: + case SI5324_DRIVE_8MA: + pdata->clkout[num].drive = val; + break; + default: + dev_err(&client->dev, + "invalid drive strength %d for clkout %d\n", + val, num); + goto put_child; + } + } + + if (!of_property_read_u32(child, "clock-frequency", &val)) { + dev_dbg(&client->dev, "clock-frequency = %u\n", val); + pdata->clkout[num].rate = val; + } else { + dev_err(&client->dev, + "missing clock-frequency property of %s\n", + child->name); + goto put_child; + } + } + client->dev.platform_data = pdata; + + return 0; +put_child: + of_node_put(child); + return -EINVAL; +} + +static u8 instance; + +static const struct i2c_device_id si5324_i2c_ids[] = { + { "si5319", si5319 }, + { "si5324", si5324 }, + { "si5328", si5328 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, si5324_i2c_ids); + +static int si5324_i2c_probe(struct i2c_client *client) +{ + const struct i2c_device_id *id = i2c_match_id(si5324_i2c_ids, client); + struct si5324_platform_data *pdata; + struct si5324_driver_data *drvdata; + struct clk_init_data init; + struct clk *clk; + const char *parent_names[3]; + char inst_names[NUM_NAME_IDS][MAX_NAME_LEN]; + u8 num_parents, num_clocks; + int ret, n; + enum si53xx_variant variant = id->driver_data; + + if (variant > si5328) { + dev_err(&client->dev, "si53xx device not present\n"); + return -ENODEV; + } + + dev_info(&client->dev, "%s probed\n", si53xx_variant_name[variant]); + ret = si5324_dt_parse(client); + if (ret) + return ret; + + pdata = client->dev.platform_data; + if (!pdata) + return -EINVAL; + + drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->client = client; + drvdata->pxtal = devm_clk_get(&client->dev, "xtal"); + drvdata->pclkin1 = devm_clk_get(&client->dev, "clkin1"); + drvdata->pclkin2 = devm_clk_get(&client->dev, "clkin2"); + + if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER || + PTR_ERR(drvdata->pclkin1) == -EPROBE_DEFER || + PTR_ERR(drvdata->pclkin2) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + drvdata->regmap = devm_regmap_init_i2c(client, &si5324_regmap_config); + if (IS_ERR(drvdata->regmap)) { + dev_err(&client->dev, "failed to allocate register map\n"); + return PTR_ERR(drvdata->regmap); + } + + i2c_set_clientdata(client, drvdata); + si5324_initialize(drvdata); + + /* setup input clock configuration */ + ret = si5324_pll_reparent(drvdata, 0, pdata->pll_src); + if (ret) { + dev_err(&client->dev, + "failed to reparent pll to %d\n", + pdata->pll_src); + return ret; + } + + for (n = 0; n < SI5324_MAX_CLKOUTS; n++) { + ret = si5324_clkout_set_drive_strength(drvdata, n, + pdata->clkout[n].drive); + if (ret) { + dev_err(&client->dev, + "failed set drive strength of clkout%d to %d\n", + n, pdata->clkout[n].drive); + return ret; + } + } + + if (!IS_ERR(drvdata->pxtal)) + clk_prepare_enable(drvdata->pxtal); + if (!IS_ERR(drvdata->pclkin1)) + clk_prepare_enable(drvdata->pclkin1); + if (!IS_ERR(drvdata->pclkin2)) + clk_prepare_enable(drvdata->pclkin2); + + /* create instance names by appending instance id */ + for (n = 0; n < SI5324_SRC_CLKS; n++) { + sprintf(inst_names[n], "%s_%d", si5324_input_names[n], + instance); + } + sprintf(inst_names[3], "%s_%d", si5324_pll_name, instance); + for (n = 0; n < SI5324_MAX_CLKOUTS; n++) { + sprintf(inst_names[n + 4], "%s_%d", si5324_clkout_names[n], + instance); + } + + /* register xtal input clock gate */ + memset(&init, 0, sizeof(init)); + init.name = inst_names[0]; + init.ops = &si5324_xtal_ops; + init.flags = 0; + + if (!IS_ERR(drvdata->pxtal)) { + drvdata->pxtal_name = __clk_get_name(drvdata->pxtal); + init.parent_names = &drvdata->pxtal_name; + init.num_parents = 1; + } + drvdata->xtal.init = &init; + + clk = devm_clk_register(&client->dev, &drvdata->xtal); + if (IS_ERR(clk)) { + dev_err(&client->dev, "unable to register %s\n", init.name); + ret = PTR_ERR(clk); + goto err_clk; + } + + /* register clkin1 input clock gate */ + memset(&init, 0, sizeof(init)); + init.name = inst_names[1]; + init.ops = &si5324_clkin_ops; + if (!IS_ERR(drvdata->pclkin1)) { + drvdata->pclkin1_name = __clk_get_name(drvdata->pclkin1); + init.parent_names = &drvdata->pclkin1_name; + init.num_parents = 1; + } + + drvdata->clkin1.init = &init; + clk = devm_clk_register(&client->dev, &drvdata->clkin1); + if (IS_ERR(clk)) { + dev_err(&client->dev, "unable to register %s\n", + init.name); + ret = PTR_ERR(clk); + goto err_clk; + } + + /* register clkin2 input clock gate */ + memset(&init, 0, sizeof(init)); + init.name = inst_names[2]; + init.ops = &si5324_clkin_ops; + if (!IS_ERR(drvdata->pclkin2)) { + drvdata->pclkin2_name = __clk_get_name(drvdata->pclkin2); + init.parent_names = &drvdata->pclkin2_name; + init.num_parents = 1; + } + + drvdata->clkin2.init = &init; + clk = devm_clk_register(&client->dev, &drvdata->clkin2); + if (IS_ERR(clk)) { + dev_err(&client->dev, "unable to register %s\n", + init.name); + ret = PTR_ERR(clk); + goto err_clk; + } + + /* Si5324 allows to mux xtal or clkin1 or clkin2 to PLL input */ + num_parents = SI5324_SRC_CLKS; + parent_names[0] = inst_names[0]; + parent_names[1] = inst_names[1]; + parent_names[2] = inst_names[2]; + + /* register PLL */ + drvdata->pll.drvdata = drvdata; + drvdata->pll.hw.init = &init; + memset(&init, 0, sizeof(init)); + init.name = inst_names[3]; + init.ops = &si5324_pll_ops; + init.flags = 0; + init.flags |= CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; + init.parent_names = parent_names; + init.num_parents = num_parents; + + clk = devm_clk_register(&client->dev, &drvdata->pll.hw); + if (IS_ERR(clk)) { + dev_err(&client->dev, "unable to register %s\n", init.name); + ret = PTR_ERR(clk); + goto err_clk; + } + + /* register clk out divider */ + num_clocks = 2; + num_parents = 1; + parent_names[0] = inst_names[3]; + + drvdata->clkout = devm_kzalloc(&client->dev, num_clocks * + sizeof(*drvdata->clkout), GFP_KERNEL); + + drvdata->onecell.clk_num = num_clocks; + drvdata->onecell.clks = devm_kzalloc(&client->dev, + num_clocks * + sizeof(*drvdata->onecell.clks), + GFP_KERNEL); + + if (WARN_ON(!drvdata->clkout) || !drvdata->onecell.clks) { + ret = -ENOMEM; + goto err_clk; + } + + for (n = 0; n < num_clocks; n++) { + drvdata->clkout[n].num = n; + drvdata->clkout[n].drvdata = drvdata; + drvdata->clkout[n].hw.init = &init; + memset(&init, 0, sizeof(init)); + init.name = inst_names[4 + n]; + init.ops = &si5324_clkout_ops; + init.flags = 0; + init.flags |= CLK_SET_RATE_PARENT; + init.parent_names = parent_names; + init.num_parents = num_parents; + + clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw); + if (IS_ERR(clk)) { + dev_err(&client->dev, "unable to register %s\n", + init.name); + ret = PTR_ERR(clk); + goto err_clk; + } + /* refer to output clock in onecell */ + drvdata->onecell.clks[n] = clk; + + /* set initial clkout rate */ + if (pdata->clkout[n].rate != 0) { + int ret; + + ret = clk_set_rate(clk, pdata->clkout[n].rate); + if (ret != 0) { + dev_err(&client->dev, "Cannot set rate : %d\n", + ret); + } + } + } + + ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, + &drvdata->onecell); + if (ret) { + dev_err(&client->dev, "unable to add clk provider\n"); + goto err_clk; + } + + dev_info(&client->dev, "%s probe successful\n", + si53xx_variant_name[variant]); + instance++; + return 0; + +err_clk: + if (!IS_ERR(drvdata->pxtal)) + clk_disable_unprepare(drvdata->pxtal); + if (!IS_ERR(drvdata->pclkin1)) + clk_disable_unprepare(drvdata->pclkin1); + if (!IS_ERR(drvdata->pclkin2)) + clk_disable_unprepare(drvdata->pclkin2); + + return ret; +} + +static void si5324_i2c_remove(struct i2c_client *client) +{ + of_clk_del_provider(client->dev.of_node); +} + +static struct i2c_driver si5324_driver = { + .driver = { + .name = "si5324", + .of_match_table = of_match_ptr(si5324_dt_ids), + }, + .probe = si5324_i2c_probe, + .remove = si5324_i2c_remove, + .id_table = si5324_i2c_ids, +}; +module_i2c_driver(si5324_driver); + +MODULE_AUTHOR("Venkateshwar Rao G "); +MODULE_DESCRIPTION("Silicon Labs 5319/5324/5328 clock driver"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/clk/clk-si5324.h +++ linux-xilinx-6.8.0/drivers/clk/clk-si5324.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Si5324 clock driver + * + * Copyright (C) 2017-2018 Xilinx, Inc. + * + * Authors: Leon Woestenberg + * Venkateshwar Rao + */ + +#ifndef _CLK_SI5324_H_ +#define _CLK_SI5324_H_ + +#define SI5324_BUS_BASE_ADDR 0x68 + +#define SI5324_CONTROL 0 +#define SI5324_CONTROL_FREE_RUN BIT(6) +#define SI5324_FREE_RUN_EN 0x54 + +#define SI5324_INCK_PRIOR 1 +#define SI5324_INCK_PRIOR_1_MASK 0xC +#define SI5324_INCK_PRIOI_2_MASK 0x3 + +#define SI5324_BWSEL 2 +#define SI5324_BWSEL_MASK 0xF0 +#define SI5324_BWSEL_SHIFT 4 +#define SI5324_BWSEL_DEF_VAL 2 + +#define SI5324_CKSEL 3 +#define SI5324_CKSEL_SQL_ICAL BIT(4) +#define SI5324_CKSEL_SHIFT 6 +#define SI5324_CK_SEL 3 + +#define SI3324_AUTOSEL 4 +#define SI5324_AUTOSEL_DEF 0x12 + +#define SI5324_ICMOS 5 +#define SI5324_OUTPUT_SIGFMT 6 +#define SI5324_OUTPUT_SF1_DEFAULT 0xF +#define SI5324_REFFRE_FOS 7 +#define SI5324_HLOG 8 +#define SI5324_AVG_HIST 9 +#define SI5324_DSBL_CLKOUT 10 +#define SI5324_DSBL_CLKOUT2 BIT(3) +#define SI5324_POWERDOWN 11 +#define SI5324_PD_CK1 BIT(0) +#define SI5324_PD_CK2 BIT(1) +#define SI5324_PD_CK1_DIS 0x41 +#define SI5324_PD_CK2_DIS 0x42 +#define SI5324_FOS_LOCKT 19 +#define SI5324_FOS_DEFAULT 0x23 +#define SI5324_CK_ACTV_SEL 21 +#define SI5324_CK_DEFAULT 0xFC +#define SI5324_CK_ACTV BIT(1) +#define SI5324_CK_SELPIN BIT(1) +#define SI5324_LOS_MSK 23 +#define SI5324_FOS_L0L_MASK 24 + +/* output clock dividers */ +#define SI5324_N1_HS 25 +#define SI5324_N1_HS_VAL_SHIFT 5 +#define SI5324_HSHIFT 16 +#define SI5324_LSHIFT 8 +#define SI5324_NC1_LS_H 31 +#define SI5324_NC1_LS_M 32 +#define SI5324_NC1_LS_L 33 +#define SI5324_DIV_LS_MASK 0x0F +#define SI5324_DIV_HS_MASK 0xF0 +#define SI5324_NC2_LS_H 34 +#define SI5324_NC2_LS_M 35 +#define SI5324_NC2_LS_L 36 + +#define SI5324_N2_HS_LS_H 40 +#define SI5324_N2_HS_LS_H_VAL_SHIFT 5 +#define SI5324_N2_LS_H 41 +#define SI5324_N2_LS_L 42 +#define SI5324_N31_CLKIN_H 43 +#define SI5324_N31_CLKIN_M 44 +#define SI5324_N31_CLKIN_L 45 +#define SI5324_N32_CLKIN_H 46 +#define SI5324_N32_CLKIN_M 47 +#define SI5324_N32_CLKIN_L 48 +#define SI5324_FOS_CLKIN_RATE 55 +#define SI5324_PLL_ACTV_CLK 128 +#define SI5324_LOS_STATUS 129 +#define SI5324_CLKIN_LOL_STATUS 130 +#define SI5324_LOS_FLG 131 +#define SI5324_FOS_FLG 132 +#define SI5324_PARTNO_H 134 +#define SI5324_PARTNO_L 135 + +#define SI5324_RESET_CALIB 136 +#define SI5324_RST_ALL BIT(7) +#define SI5324_CALIB_EN BIT(6) + +#define SI5324_FASTLOCK 137 +#define SI5324_FASTLOCK_EN BIT(0) +#define SI5324_LOS1_LOS2_EN 138 +#define SI5324_SKEW1 142 +#define SI5324_SKEW2 143 + +/* selects 2kHz to 710 MHz */ +#define SI5324_CLKIN_MIN_FREQ 2000 +#define SI5324_CLKIN_MAX_FREQ (710 * 1000 * 1000) + +/* generates 2kHz to 945 MHz */ +#define SI5324_CLKOUT_MIN_FREQ 2000 +#define SI5324_CLKOUT_MAX_FREQ (945 * 1000 * 1000) + +/* The following constants define the limits of the divider settings. */ +#define SI5324_N1_HS_MIN 6 +#define SI5324_N1_HS_MAX 11 +#define SI5324_NC_LS_MIN 1 +#define SI5324_NC_LS_MAX 0x100000 +#define SI5324_N2_HS_MIN 4 +#define SI5324_N2_HS_MAX 11 +#define SI5324_N2_LS_MIN 2 +#define SI5324_N2_LS_MAX 0x100000 +#define SI5324_N3_MIN 1 +#define SI5324_N3_MAX 0x080000 + +#define SI5324_SRC_XTAL 0 +#define SI5324_SRC_CLKIN1 1 +#define SI5324_SRC_CLKIN2 2 +#define SI5324_SRC_CLKS 3 + +#define SI5324_CLKIN1 0 +#define SI5324_CLKIN2 1 +#define SI5324_MAX_CLKOUTS 2 +#define NUM_NAME_IDS 6 /* 3 clkin, 1 pll, 2 clkout */ +#define MAX_NAME_LEN 11 +#define SI5324_PARAM_LEN 24 +#define SI5324_NC_PARAM_LEN 6 +#define SI5324_OUT_REGS 14 +#define SI5324_N1_PARAM_LEN 1 +#define SI5324_N2_PARAM_LEN 9 +#define SI5324_REF_CLOCK 114285000UL +#define SI5324_RESET_DELAY_MS 20 + +#endif --- linux-xilinx-6.8.0.orig/drivers/clk/clk.c +++ linux-xilinx-6.8.0/drivers/clk/clk.c @@ -37,6 +37,10 @@ static HLIST_HEAD(clk_orphan_list); static LIST_HEAD(clk_notifier_list); +/* List of registered clks that use runtime PM */ +static HLIST_HEAD(clk_rpm_list); +static DEFINE_MUTEX(clk_rpm_list_lock); + static const struct hlist_head *all_lists[] = { &clk_root_list, &clk_orphan_list, @@ -59,6 +63,7 @@ struct clk_hw *hw; struct module *owner; struct device *dev; + struct hlist_node rpm_node; struct device_node *of_node; struct clk_core *parent; struct clk_parent_map *parents; @@ -122,6 +127,89 @@ pm_runtime_put_sync(core->dev); } +/** + * clk_pm_runtime_get_all() - Runtime "get" all clk provider devices + * + * Call clk_pm_runtime_get() on all runtime PM enabled clks in the clk tree so + * that disabling unused clks avoids a deadlock where a device is runtime PM + * resuming/suspending and the runtime PM callback is trying to grab the + * prepare_lock for something like clk_prepare_enable() while + * clk_disable_unused_subtree() holds the prepare_lock and is trying to runtime + * PM resume/suspend the device as well. + * + * Context: Acquires the 'clk_rpm_list_lock' and returns with the lock held on + * success. Otherwise the lock is released on failure. + * + * Return: 0 on success, negative errno otherwise. + */ +static int clk_pm_runtime_get_all(void) +{ + int ret; + struct clk_core *core, *failed; + + /* + * Grab the list lock to prevent any new clks from being registered + * or unregistered until clk_pm_runtime_put_all(). + */ + mutex_lock(&clk_rpm_list_lock); + + /* + * Runtime PM "get" all the devices that are needed for the clks + * currently registered. Do this without holding the prepare_lock, to + * avoid the deadlock. + */ + hlist_for_each_entry(core, &clk_rpm_list, rpm_node) { + ret = clk_pm_runtime_get(core); + if (ret) { + failed = core; + pr_err("clk: Failed to runtime PM get '%s' for clk '%s'\n", + dev_name(failed->dev), failed->name); + goto err; + } + } + + return 0; + +err: + hlist_for_each_entry(core, &clk_rpm_list, rpm_node) { + if (core == failed) + break; + + clk_pm_runtime_put(core); + } + mutex_unlock(&clk_rpm_list_lock); + + return ret; +} + +/** + * clk_pm_runtime_put_all() - Runtime "put" all clk provider devices + * + * Put the runtime PM references taken in clk_pm_runtime_get_all() and release + * the 'clk_rpm_list_lock'. + */ +static void clk_pm_runtime_put_all(void) +{ + struct clk_core *core; + + hlist_for_each_entry(core, &clk_rpm_list, rpm_node) + clk_pm_runtime_put(core); + mutex_unlock(&clk_rpm_list_lock); +} + +static void clk_pm_runtime_init(struct clk_core *core) +{ + struct device *dev = core->dev; + + if (dev && pm_runtime_enabled(dev)) { + core->rpm_enabled = true; + + mutex_lock(&clk_rpm_list_lock); + hlist_add_head(&core->rpm_node, &clk_rpm_list); + mutex_unlock(&clk_rpm_list_lock); + } +} + /*** locking ***/ static void clk_prepare_lock(void) { @@ -418,6 +506,9 @@ if (IS_ERR(hw)) return ERR_CAST(hw); + if (!hw) + return NULL; + return hw->core; } @@ -939,6 +1030,25 @@ } EXPORT_SYMBOL_GPL(clk_rate_exclusive_get); +static void devm_clk_rate_exclusive_put(void *data) +{ + struct clk *clk = data; + + clk_rate_exclusive_put(clk); +} + +int devm_clk_rate_exclusive_get(struct device *dev, struct clk *clk) +{ + int ret; + + ret = clk_rate_exclusive_get(clk); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, devm_clk_rate_exclusive_put, clk); +} +EXPORT_SYMBOL_GPL(devm_clk_rate_exclusive_get); + static void clk_core_unprepare(struct clk_core *core) { lockdep_assert_held(&prepare_lock); @@ -1359,9 +1469,6 @@ if (core->flags & CLK_IGNORE_UNUSED) return; - if (clk_pm_runtime_get(core)) - return; - if (clk_core_is_prepared(core)) { trace_clk_unprepare(core); if (core->ops->unprepare_unused) @@ -1370,8 +1477,6 @@ core->ops->unprepare(core->hw); trace_clk_unprepare_complete(core); } - - clk_pm_runtime_put(core); } static void __init clk_disable_unused_subtree(struct clk_core *core) @@ -1387,9 +1492,6 @@ if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_prepare_enable(core->parent); - if (clk_pm_runtime_get(core)) - goto unprepare_out; - flags = clk_enable_lock(); if (core->enable_count) @@ -1414,8 +1516,6 @@ unlock_out: clk_enable_unlock(flags); - clk_pm_runtime_put(core); -unprepare_out: if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_disable_unprepare(core->parent); } @@ -1431,6 +1531,7 @@ static int __init clk_disable_unused(void) { struct clk_core *core; + int ret; if (clk_ignore_unused) { pr_warn("clk: Not disabling unused clocks\n"); @@ -1439,6 +1540,13 @@ pr_info("clk: Disabling unused clocks\n"); + ret = clk_pm_runtime_get_all(); + if (ret) + return ret; + /* + * Grab the prepare lock to keep the clk topology stable while iterating + * over clks. + */ clk_prepare_lock(); hlist_for_each_entry(core, &clk_root_list, child_node) @@ -1455,6 +1563,8 @@ clk_prepare_unlock(); + clk_pm_runtime_put_all(); + return 0; } late_initcall_sync(clk_disable_unused); @@ -3230,9 +3340,7 @@ { struct clk_core *child; - clk_pm_runtime_get(c); clk_summary_show_one(s, c, level); - clk_pm_runtime_put(c); hlist_for_each_entry(child, &c->children, child_node) clk_summary_show_subtree(s, child, level + 1); @@ -3242,11 +3350,15 @@ { struct clk_core *c; struct hlist_head **lists = s->private; + int ret; seq_puts(s, " enable prepare protect duty hardware connection\n"); seq_puts(s, " clock count count count rate accuracy phase cycle enable consumer id\n"); seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n"); + ret = clk_pm_runtime_get_all(); + if (ret) + return ret; clk_prepare_lock(); @@ -3255,6 +3367,7 @@ clk_summary_show_subtree(s, c, 0); clk_prepare_unlock(); + clk_pm_runtime_put_all(); return 0; } @@ -3302,8 +3415,14 @@ struct clk_core *c; bool first_node = true; struct hlist_head **lists = s->private; + int ret; + + ret = clk_pm_runtime_get_all(); + if (ret) + return ret; seq_putc(s, '{'); + clk_prepare_lock(); for (; *lists; lists++) { @@ -3316,6 +3435,7 @@ } clk_prepare_unlock(); + clk_pm_runtime_put_all(); seq_puts(s, "}\n"); return 0; @@ -3959,8 +4079,6 @@ } clk_core_reparent_orphans_nolock(); - - kref_init(&core->ref); out: clk_pm_runtime_put(core); unlock: @@ -4189,6 +4307,22 @@ kfree(core->parents); } +/* Free memory allocated for a struct clk_core */ +static void __clk_release(struct kref *ref) +{ + struct clk_core *core = container_of(ref, struct clk_core, ref); + + if (core->rpm_enabled) { + mutex_lock(&clk_rpm_list_lock); + hlist_del(&core->rpm_node); + mutex_unlock(&clk_rpm_list_lock); + } + + clk_core_free_parent_map(core); + kfree_const(core->name); + kfree(core); +} + static struct clk * __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) { @@ -4209,6 +4343,8 @@ goto fail_out; } + kref_init(&core->ref); + core->name = kstrdup_const(init->name, GFP_KERNEL); if (!core->name) { ret = -ENOMEM; @@ -4221,9 +4357,8 @@ } core->ops = init->ops; - if (dev && pm_runtime_enabled(dev)) - core->rpm_enabled = true; core->dev = dev; + clk_pm_runtime_init(core); core->of_node = np; if (dev && dev->driver) core->owner = dev->driver->owner; @@ -4263,12 +4398,10 @@ hw->clk = NULL; fail_create_clk: - clk_core_free_parent_map(core); fail_parents: fail_ops: - kfree_const(core->name); fail_name: - kfree(core); + kref_put(&core->ref, __clk_release); fail_out: return ERR_PTR(ret); } @@ -4348,18 +4481,6 @@ } EXPORT_SYMBOL_GPL(of_clk_hw_register); -/* Free memory allocated for a clock. */ -static void __clk_release(struct kref *ref) -{ - struct clk_core *core = container_of(ref, struct clk_core, ref); - - lockdep_assert_held(&prepare_lock); - - clk_core_free_parent_map(core); - kfree_const(core->name); - kfree(core); -} - /* * Empty clk_ops for unregistered clocks. These are used temporarily * after clk_unregister() was called on a clock and until last clock @@ -4450,7 +4571,8 @@ if (ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - goto unlock; + clk_prepare_unlock(); + return; } /* * Assign empty clock ops for consumers that might still hold @@ -4484,11 +4606,10 @@ if (clk->core->protect_count) pr_warn("%s: unregistering protected clock: %s\n", __func__, clk->core->name); + clk_prepare_unlock(); kref_put(&clk->core->ref, __clk_release); free_clk(clk); -unlock: - clk_prepare_unlock(); } EXPORT_SYMBOL_GPL(clk_unregister); @@ -4647,13 +4768,11 @@ if (clk->min_rate > 0 || clk->max_rate < ULONG_MAX) clk_set_rate_range_nolock(clk, 0, ULONG_MAX); - owner = clk->core->owner; - kref_put(&clk->core->ref, __clk_release); - clk_prepare_unlock(); + owner = clk->core->owner; + kref_put(&clk->core->ref, __clk_release); module_put(owner); - free_clk(clk); } --- linux-xilinx-6.8.0.orig/drivers/clk/clkdev.c +++ linux-xilinx-6.8.0/drivers/clk/clkdev.c @@ -144,7 +144,7 @@ mutex_unlock(&clocks_mutex); } -#define MAX_DEV_ID 20 +#define MAX_DEV_ID 24 #define MAX_CON_ID 16 struct clk_lookup_alloc { --- linux-xilinx-6.8.0.orig/drivers/clk/hisilicon/clk-hi3519.c +++ linux-xilinx-6.8.0/drivers/clk/hisilicon/clk-hi3519.c @@ -130,7 +130,7 @@ of_clk_del_provider(pdev->dev.of_node); hisi_clk_unregister_gate(hi3519_gate_clks, - ARRAY_SIZE(hi3519_mux_clks), + ARRAY_SIZE(hi3519_gate_clks), crg->clk_data); hisi_clk_unregister_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks), --- linux-xilinx-6.8.0.orig/drivers/clk/hisilicon/clk-hi3559a.c +++ linux-xilinx-6.8.0/drivers/clk/hisilicon/clk-hi3559a.c @@ -491,7 +491,6 @@ clk = clk_register(NULL, &p_clk->hw); if (IS_ERR(clk)) { - devm_kfree(dev, p_clk); dev_err(dev, "%s: failed to register clock %s\n", __func__, clks[i].name); continue; --- linux-xilinx-6.8.0.orig/drivers/clk/idt/Makefile +++ linux-xilinx-6.8.0/drivers/clk/idt/Makefile @@ -0,0 +1,3 @@ +obj-y += clk-idt8t49n24x-core.o +obj-y += clk-idt8t49n24x-debugfs.o +obj-y += clk-idt8t49n24x.o --- linux-xilinx-6.8.0.orig/drivers/clk/idt/clk-idt8t49n24x-core.c +++ linux-xilinx-6.8.0/drivers/clk/idt/clk-idt8t49n24x-core.c @@ -0,0 +1,933 @@ +// SPDX-License-Identifier: GPL-2.0 +/* clk-idt8t49n24x-core.c - Program 8T49N24x settings via I2C (common code) + * + * Copyright (C) 2018, Integrated Device Technology, Inc. + * + * See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html + * This program is distributed "AS IS" and WITHOUT ANY WARRANTY; + * including the implied warranties of MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, or NON-INFRINGEMENT. + */ + +#include +#include + +#include "clk-idt8t49n24x-core.h" + +/* + * In Timing Commander, Q0 is changed from 25MHz to Q0 75MHz, the following + * changes occur: + * + * 2 bytes change in EEPROM data string. + * + * DSM_INT R0025[0],R0026[7:0] : 35 => 30 + * NS2_Q0 R0040[7:0],R0041[7:0] : 14 => 4 + * + * In EEPROM + * 1. R0026 + * 2. R0041 + * + * Note that VCO_Frequency (metadata) also changed (3500 =>3000). + * This reflects a change to DSM_INT. + * + * Note that the Timing Commander code has workarounds in the workflow scripts + * to handle dividers for the 8T49N241 (because the development of that GUI + * predates chip override functionality). That affects NS1_Qx (x in 1-3) + * and NS2_Qx. NS1_Qx contains the upper bits of NS_Qx, and NS2_Qx contains + * the lower bits. That is NOT the case for Q0, though. In that case NS1_Q0 + * is the 1st stage output divider (/5, /6, /4) and NS2_Q0 is the 16-bit + * second stage (with actual divide being twice the value stored in the + * register). + * + * NS1_Q0 R003F[1:0] + */ + +#define IDT24x_VCO_MIN 2999997000u +#define IDT24x_VCO_MAX 4000004000u +#define IDT24x_VCO_OPT 3500000000u +#define IDT24x_MIN_INT_DIVIDER 6 +#define IDT24x_MIN_NS1 4 +#define IDT24x_MAX_NS1 6 + +static u8 q0_ns1_options[3] = { 5, 6, 4 }; + +/** + * bits_to_shift - num bits to shift given specified mask + * @mask: 32-bit word input to count zero bits on right + * + * Given a bit mask indicating where a value will be stored in + * a register, return the number of bits you need to shift the value + * before ORing it into the register value. + * + * Return: number of bits to shift + */ +int bits_to_shift(unsigned int mask) +{ + /* the number of zero bits on the right */ + unsigned int c = 32; + + mask &= ~mask + 1; + if (mask) + c--; + if (mask & 0x0000FFFF) + c -= 16; + if (mask & 0x00FF00FF) + c -= 8; + if (mask & 0x0F0F0F0F) + c -= 4; + if (mask & 0x33333333) + c -= 2; + if (mask & 0x55555555) + c -= 1; + return c; +} + +/* + * TODO: Consider replacing this with regmap_multi_reg_write, which + * supports introducing a delay after each write. Experiment to see if + * the writes succeed consistently when using that API. + */ +static int regmap_bulk_write_with_retry( + struct regmap *map, unsigned int offset, u8 val[], + int val_count, int max_attempts) +{ + int err = 0; + int count = 1; + + do { + err = regmap_bulk_write(map, offset, val, val_count); + if (err == 0) + return 0; + + usleep_range(100, 200); + } while (count++ <= max_attempts); + return err; +} + +static int regmap_write_with_retry( + struct regmap *map, unsigned int offset, unsigned int val, + int max_attempts) +{ + int err = 0; + int count = 1; + + do { + err = regmap_write(map, offset, val); + if (err == 0) + return 0; + usleep_range(100, 200); + } while (count++ <= max_attempts); + return err; +} + +/* + * TODO: Consider using regmap_multi_reg_write instead. Explore + * use of regmap to configure WRITE_BLOCK_SIZE, and using the delay + * mechanism in regmap_multi_reg_write instead of retrying multiple + * times (regmap_bulk_write_with_retry). + */ +int i2cwritebulk( + struct i2c_client *client, struct regmap *map, + unsigned int reg, u8 val[], size_t val_count) +{ + char dbg[128]; + u8 block[WRITE_BLOCK_SIZE]; + unsigned int block_offset = reg; + int x; + int err = 0; + int currentOffset = 0; + + dev_dbg(&client->dev, "I2C->0x%04x : [hex] . First byte: %02x, Second byte: %02x", + reg, reg >> 8, reg & 0xFF); + dbg[0] = 0; + + for (x = 0; x < val_count; x++) { + char data[4]; + + block[currentOffset++] = val[x]; + sprintf(data, "%02x ", val[x]); + strcat(dbg, data); + if (x > 0 && (x + 1) % WRITE_BLOCK_SIZE == 0) { + dev_dbg(&client->dev, "%s", dbg); + dbg[0] = '\0'; + sprintf(dbg, + "(loop) calling regmap_bulk_write @ 0x%04x [%d bytes]", + block_offset, WRITE_BLOCK_SIZE); + dev_dbg(&client->dev, "%s", dbg); + dbg[0] = '\0'; + err = regmap_bulk_write_with_retry( + map, block_offset, block, WRITE_BLOCK_SIZE, 5); + if (err != 0) + break; + block_offset += WRITE_BLOCK_SIZE; + currentOffset = 0; + } + } + if (err == 0 && currentOffset > 0) { + dev_dbg(&client->dev, "%s", dbg); + dev_dbg(&client->dev, "(final) calling regmap_bulk_write @ 0x%04x [%d bytes]", + block_offset, currentOffset); + err = regmap_bulk_write_with_retry( + map, block_offset, block, currentOffset, 5); + } + + return err; +} + +static int i2cwrite( + struct i2c_client *client, struct regmap *map, + unsigned int reg, unsigned int val) +{ + int err; + + dev_dbg(&client->dev, "I2C->0x%x : [hex] %x", reg, val); + err = regmap_write_with_retry(map, reg, val, 5); + usleep_range(100, 200); + return err; +} + +static int i2cwritewithmask( + struct i2c_client *client, struct regmap *map, unsigned int reg, + u8 val, u8 original, u8 mask) +{ + return i2cwrite(client, map, reg, + ((val << bits_to_shift(mask)) & mask) | (original & ~mask)); +} + +int idt24x_get_offsets( + u8 output_num, + struct clk_register_offsets *offsets) +{ + switch (output_num) { + case 0: + offsets->oe_offset = IDT24x_REG_OUTEN; + offsets->oe_mask = IDT24x_REG_OUTEN0_MASK; + offsets->dis_mask = IDT24x_REG_Q0_DIS_MASK; + offsets->ns1_offset = IDT24x_REG_NS1_Q0; + offsets->ns1_offset_mask = IDT24x_REG_NS1_Q0_MASK; + offsets->ns2_15_8_offset = IDT24x_REG_NS2_Q0_15_8; + offsets->ns2_7_0_offset = IDT24x_REG_NS2_Q0_7_0; + break; + case 1: + offsets->oe_offset = IDT24x_REG_OUTEN; + offsets->oe_mask = IDT24x_REG_OUTEN1_MASK; + offsets->dis_mask = IDT24x_REG_Q1_DIS_MASK; + offsets->n_17_16_offset = IDT24x_REG_N_Q1_17_16; + offsets->n_17_16_mask = IDT24x_REG_N_Q1_17_16_MASK; + offsets->n_15_8_offset = IDT24x_REG_N_Q1_15_8; + offsets->n_7_0_offset = IDT24x_REG_N_Q1_7_0; + offsets->nfrac_27_24_offset = IDT24x_REG_NFRAC_Q1_27_24; + offsets->nfrac_27_24_mask = + IDT24x_REG_NFRAC_Q1_27_24_MASK; + offsets->nfrac_23_16_offset = IDT24x_REG_NFRAC_Q1_23_16; + offsets->nfrac_15_8_offset = IDT24x_REG_NFRAC_Q1_15_8; + offsets->nfrac_7_0_offset = IDT24x_REG_NFRAC_Q1_7_0; + break; + case 2: + offsets->oe_offset = IDT24x_REG_OUTEN; + offsets->oe_mask = IDT24x_REG_OUTEN2_MASK; + offsets->dis_mask = IDT24x_REG_Q2_DIS_MASK; + offsets->n_17_16_offset = IDT24x_REG_N_Q2_17_16; + offsets->n_17_16_mask = IDT24x_REG_N_Q2_17_16_MASK; + offsets->n_15_8_offset = IDT24x_REG_N_Q2_15_8; + offsets->n_7_0_offset = IDT24x_REG_N_Q2_7_0; + offsets->nfrac_27_24_offset = IDT24x_REG_NFRAC_Q2_27_24; + offsets->nfrac_27_24_mask = + IDT24x_REG_NFRAC_Q2_27_24_MASK; + offsets->nfrac_23_16_offset = IDT24x_REG_NFRAC_Q2_23_16; + offsets->nfrac_15_8_offset = IDT24x_REG_NFRAC_Q2_15_8; + offsets->nfrac_7_0_offset = IDT24x_REG_NFRAC_Q2_7_0; + break; + case 3: + offsets->oe_offset = IDT24x_REG_OUTEN; + offsets->oe_mask = IDT24x_REG_OUTEN3_MASK; + offsets->dis_mask = IDT24x_REG_Q3_DIS_MASK; + offsets->n_17_16_offset = IDT24x_REG_N_Q3_17_16; + offsets->n_17_16_mask = IDT24x_REG_N_Q3_17_16_MASK; + offsets->n_15_8_offset = IDT24x_REG_N_Q3_15_8; + offsets->n_7_0_offset = IDT24x_REG_N_Q3_7_0; + offsets->nfrac_27_24_offset = IDT24x_REG_NFRAC_Q3_27_24; + offsets->nfrac_27_24_mask = + IDT24x_REG_NFRAC_Q3_27_24_MASK; + offsets->nfrac_23_16_offset = IDT24x_REG_NFRAC_Q3_23_16; + offsets->nfrac_15_8_offset = IDT24x_REG_NFRAC_Q3_15_8; + offsets->nfrac_7_0_offset = IDT24x_REG_NFRAC_Q3_7_0; + break; + default: + return -EINVAL; + } + return 0; +} + +/** + * idt24x_calc_div_q0 - Calculate dividers and VCO freq to generate + * the specified Q0 frequency. + * @chip: Device data structure. contains all requested frequencies + * for all outputs. + * + * The actual output divider is ns1 * ns2 * 2. fOutput = fVCO / (ns1 * ns2 * 2) + * + * The options for ns1 (when the source is the VCO) are 4,5,6. ns2 is a + * 16-bit value. + * + * chip->divs: structure for specifying ns1/ns2 values. If 0 after this + * function, Q0 is not requested + * + * Return: 0 on success, negative errno otherwise. + */ +static int idt24x_calc_div_q0(struct clk_idt24x_chip *chip) +{ + u8 x; + u32 min_div, max_div, best_vco = 0; + u16 min_ns2, max_ns2; + bool is_lower_vco = false; + + chip->divs.ns1_q0 = 0; + chip->divs.ns2_q0 = 0; + + if (chip->clk[0].requested == 0) + return 0; + + min_div = div64_u64( + (u64)IDT24x_VCO_MIN, chip->clk[0].requested * 2) * 2; + max_div = div64_u64( + (u64)IDT24x_VCO_MAX, chip->clk[0].requested * 2) * 2; + + dev_dbg(&chip->i2c_client->dev, + "%s. requested: %u, min_div: %u, max_div: %u", + __func__, chip->clk[0].requested, min_div, max_div); + + min_ns2 = div64_u64((u64)min_div, IDT24x_MAX_NS1 * 2); + max_ns2 = div64_u64((u64)max_div, IDT24x_MIN_NS1 * 2); + + dev_dbg(&chip->i2c_client->dev, + "%s. min_ns2: %u, max_ns2: %u", __func__, min_ns2, max_ns2); + + for (x = 0; x < ARRAY_SIZE(q0_ns1_options); x++) { + u16 y = min_ns2; + + while (y <= max_ns2) { + u32 actual_div = q0_ns1_options[x] * y * 2; + u32 current_vco = actual_div * + chip->clk[0].requested; + + if (current_vco < IDT24x_VCO_MIN) + dev_dbg(&chip->i2c_client->dev, + "%s. ignore div: (ns1=%u * ns2=%u * 2 * %u) == %u < %u", + __func__, q0_ns1_options[x], y, + chip->clk[0].requested, + current_vco, IDT24x_VCO_MIN); + else if (current_vco > IDT24x_VCO_MAX) { + dev_dbg(&chip->i2c_client->dev, + "%s. ignore div: (ns1=%u * ns2=%u * 2 * %u) == %u > %u. EXIT LOOP.", + __func__, q0_ns1_options[x], y, + chip->clk[0].requested, + current_vco, IDT24x_VCO_MAX); + y = max_ns2; + } else { + bool use = false; + + dev_dbg(&chip->i2c_client->dev, + "%s. contender: (ns1=%u * ns2=%u * 2 * %u) == %u [in range]", + __func__, q0_ns1_options[x], y, + chip->clk[0].requested, + current_vco); + if (current_vco <= IDT24x_VCO_OPT) { + if (current_vco > best_vco || + !is_lower_vco) { + is_lower_vco = true; + use = true; + } + } else if (!is_lower_vco && + current_vco > best_vco) + use = true; + if (use) { + chip->divs.ns1_q0 = x; + chip->divs.ns2_q0 = y; + best_vco = current_vco; + } + } + y++; + } + } + + dev_dbg(&chip->i2c_client->dev, + "%s. best: (ns1=%u [/%u] * ns2=%u * 2 * %u) == %u", + __func__, chip->divs.ns1_q0, q0_ns1_options[chip->divs.ns1_q0], + chip->divs.ns2_q0, chip->clk[0].requested, best_vco); + return 0; +} + +/** + * idt24x_calc_divs - Calculate dividers to generate the specified frequency. + * @chip: Device data structure. contains all requested frequencies + * for all outputs. + * + * Calculate the clock dividers (dsmint, dsmfrac for vco; ns1/ns2 for q0, + * n/nfrac for q1-3) for a given target frequency. + * + * Return: 0 on success, negative errno otherwise. + */ +static int idt24x_calc_divs(struct clk_idt24x_chip *chip) +{ + u32 vco = 0; + int result; + + result = idt24x_calc_div_q0(chip); + if (result < 0) + return result; + + dev_dbg(&chip->i2c_client->dev, + "%s: after idt24x_calc_div_q0. ns1: %u [/%u], ns2: %u", + __func__, chip->divs.ns1_q0, q0_ns1_options[chip->divs.ns1_q0], + chip->divs.ns2_q0); + + chip->divs.dsmint = 0; + chip->divs.dsmfrac = 0; + + if (chip->clk[0].requested > 0) { + /* Q0 is in use and is governing the actual VCO freq */ + vco = q0_ns1_options[chip->divs.ns1_q0] * chip->divs.ns2_q0 * + 2 * chip->clk[0].requested; + } else { + u32 freq = 0; + u32 walk; + u32 min_div, max_div; + bool is_lower_vco = false; + + /* + * Q0 is not in use. Use the first requested (fractional) + * output frequency as the one controlling the VCO. + */ + for (walk = 1; walk < NUM_OUTPUTS; walk++) { + if (chip->clk[walk].requested != 0) { + freq = chip->clk[walk].requested; + break; + } + } + + if (freq == 0) { + dev_err(&chip->i2c_client->dev, + "%s: NO FREQUENCIES SPECIFIED", __func__); + return -EINVAL; + } + + /* + * First, determine the min/max div for the output frequency. + */ + min_div = IDT24x_MIN_INT_DIVIDER; + max_div = div64_u64((u64)IDT24x_VCO_MAX, freq * 2) * 2; + + dev_dbg(&chip->i2c_client->dev, + "%s: calc_divs for fractional output. freq: %u, min_div: %u, max_div: %u", + __func__, freq, min_div, max_div); + + walk = min_div; + + while (walk <= max_div) { + u32 current_vco = freq * walk; + + dev_dbg(&chip->i2c_client->dev, + "%s: calc_divs for fractional output. walk: %u, freq: %u, vco: %u", + __func__, walk, freq, vco); + if (current_vco >= IDT24x_VCO_MIN && + vco <= IDT24x_VCO_MAX) { + if (current_vco <= IDT24x_VCO_OPT) { + if (current_vco > vco || + !is_lower_vco) { + is_lower_vco = true; + vco = current_vco; + } + } else if (!is_lower_vco && current_vco > vco) { + vco = current_vco; + } + } + /* Divider must be even. */ + walk += 2; + } + } + + if (vco != 0) { + u32 pfd; + u64 rem; + int x; + + /* Setup dividers for outputs with fractional dividers. */ + for (x = 1; x < NUM_OUTPUTS; x++) { + if (chip->clk[x].requested != 0) { + /* + * The value written to the chip is half + * the calculated divider. + */ + chip->divs.nint[x - 1] = div64_u64_rem( + (u64)vco, + chip->clk[x].requested * 2, + &rem); + chip->divs.nfrac[x - 1] = div64_u64( + rem * 1 << 28, + chip->clk[x].requested * 2); + dev_dbg(&chip->i2c_client->dev, + "%s: div to get Q%i freq %u from vco %u: int part: %u, rem: %llu, frac part: %u", + __func__, x, + chip->clk[x].requested, + vco, chip->divs.nint[x - 1], rem, + chip->divs.nfrac[x - 1]); + } + } + + /* Calculate freq for pfd */ + pfd = chip->input_clk_freq * (chip->doubler_disabled ? 1 : 2); + + /* + * Calculate dsmint & dsmfrac: + * ----------------------------- + * dsm = float(vco)/float(pfd) + * dsmfrac = dsm-floor(dsm) * 2^21 + * rem = vco % pfd + * therefore: + * dsmfrac = (rem * 2^21)/pfd + */ + chip->divs.dsmint = div64_u64_rem(vco, pfd, &rem); + chip->divs.dsmfrac = div64_u64(rem * 1 << 21, pfd); + + dev_dbg(&chip->i2c_client->dev, + "%s: vco: %u, pfd: %u, dsmint: %u, dsmfrac: %u, rem: %llu", + __func__, vco, pfd, chip->divs.dsmint, + chip->divs.dsmfrac, rem); + } else { + dev_err(&chip->i2c_client->dev, + "%s: no integer divider in range found. NOT SUPPORTED.", + __func__); + return -EINVAL; + } + return 0; +} + +/** + * idt24x_enable_output - Enable/disable a particular output + * @chip: Device data structure + * @output: Output to enable/disable + * @enable: Enable (true/false) + * + * Return: passes on regmap_write return value. + */ +static int idt24x_enable_output( + struct clk_idt24x_chip *chip, u8 output, bool enable) +{ + struct clk_register_offsets offsets; + int err; + struct i2c_client *client = chip->i2c_client; + + /* + * When an output is enabled, enable it in the original + * data read from the chip and cached. Otherwise it may be + * accidentally turned off when another output is enabled. + * + * E.g., the driver starts with all outputs off in reg_out_en_x. + * Q1 is enabled with the appropriate mask. Q2 is then enabled, + * which results in Q1 being turned back off (because Q1 was off + * in reg_out_en_x). + */ + + err = idt24x_get_offsets(output, &offsets); + if (err) { + dev_err(&client->dev, + "%s: error calling idt24x_get_offsets for %d: %i", + __func__, output, err); + return err; + } + + dev_dbg(&client->dev, + "%s: q%u enable? %d. reg_out_en_x before: 0x%x, reg_out_mode_0_1 before: 0x%x, reg_out_mode_2_3 before: 0x%x, reg_qx_dis before: 0x%x", + __func__, output, enable, chip->reg_out_en_x, + chip->reg_out_mode_0_1, chip->reg_out_mode_2_3, + chip->reg_qx_dis); + + chip->reg_out_en_x = chip->reg_out_en_x & ~offsets.oe_mask; + if (enable) + chip->reg_out_en_x |= (1 << bits_to_shift(offsets.oe_mask)); + + chip->reg_qx_dis = chip->reg_qx_dis & ~offsets.dis_mask; + dev_dbg(&client->dev, + "%s: q%u enable? %d. reg_qx_dis mask: 0x%x, before checking enable: 0x%x", + __func__, output, enable, offsets.dis_mask, + chip->reg_qx_dis); + if (!enable) + chip->reg_qx_dis |= (1 << bits_to_shift(offsets.dis_mask)); + + dev_dbg(&client->dev, + "%s: q%u enable? %d. reg_out_en_x after: 0x%x, reg_qx_dis after: 0x%x", + __func__, output, enable, chip->reg_out_en_x, + chip->reg_qx_dis); + + err = i2cwrite( + client, chip->regmap, IDT24x_REG_OUTEN, chip->reg_out_en_x); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_OUTEN: %i", + __func__, err); + return err; + } + + err = i2cwrite( + client, chip->regmap, IDT24x_REG_OUTMODE0_1, + chip->reg_out_mode_0_1); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_OUTMODE0_1: %i", + __func__, err); + return err; + } + + err = i2cwrite( + client, chip->regmap, IDT24x_REG_OUTMODE2_3, + chip->reg_out_mode_2_3); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_OUTMODE2_3: %i", + __func__, err); + return err; + } + + err = i2cwrite( + client, chip->regmap, IDT24x_REG_Q_DIS, chip->reg_qx_dis); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_Q_DIS: %i", + __func__, err); + return err; + } + + return 0; +} + +/** + * idt24x_update_device - write registers to the chip + * @chip: Device data structure + * + * Write all values to hardware that we have calculated. + * + * Return: passes on regmap_bulk_write return value. + */ +static int idt24x_update_device(struct clk_idt24x_chip *chip) +{ + int err; + struct i2c_client *client = chip->i2c_client; + int x = -1; + + dev_dbg(&client->dev, + "%s: setting DSM_INT_8 (val %u @ %u)", + __func__, chip->divs.dsmint >> 8, + IDT24x_REG_DSM_INT_8); + err = i2cwritewithmask( + client, chip->regmap, IDT24x_REG_DSM_INT_8, + (chip->divs.dsmint >> 8) & IDT24x_REG_DSM_INT_8_MASK, + chip->reg_dsm_int_8, IDT24x_REG_DSM_INT_8_MASK); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_DSM_INT_8: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting DSM_INT_7_0 (val %u @ 0x%x)", + __func__, chip->divs.dsmint & 0xFF, + IDT24x_REG_DSM_INT_7_0); + err = i2cwrite( + client, chip->regmap, IDT24x_REG_DSM_INT_7_0, + chip->divs.dsmint & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_DSM_INT_7_0: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting IDT24x_REG_DSMFRAC_20_16 (val %u @ 0x%x)", + __func__, chip->divs.dsmfrac >> 16, + IDT24x_REG_DSMFRAC_20_16); + err = i2cwritewithmask( + client, chip->regmap, IDT24x_REG_DSMFRAC_20_16, + (chip->divs.dsmfrac >> 16) & IDT24x_REG_DSMFRAC_20_16_MASK, + chip->reg_dsm_int_8, IDT24x_REG_DSMFRAC_20_16_MASK); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_DSMFRAC_20_16: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting IDT24x_REG_DSMFRAC_15_8 (val %u @ 0x%x)", + __func__, (chip->divs.dsmfrac >> 8) & 0xFF, + IDT24x_REG_DSMFRAC_15_8); + err = i2cwrite( + client, chip->regmap, IDT24x_REG_DSMFRAC_15_8, + (chip->divs.dsmfrac >> 8) & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_DSMFRAC_15_8: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting IDT24x_REG_DSMFRAC_7_0 (val %u @ 0x%x)", + __func__, chip->divs.dsmfrac & 0xFF, + IDT24x_REG_DSMFRAC_7_0); + err = i2cwrite( + client, chip->regmap, IDT24x_REG_DSMFRAC_7_0, + chip->divs.dsmfrac & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_DSMFRAC_7_0: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting IDT24x_REG_NS1_Q0 (val %u @ 0x%x)", + __func__, chip->divs.ns1_q0, IDT24x_REG_NS1_Q0); + err = i2cwritewithmask( + client, chip->regmap, IDT24x_REG_NS1_Q0, + chip->divs.ns1_q0 & IDT24x_REG_NS1_Q0_MASK, + chip->reg_ns1_q0, IDT24x_REG_NS1_Q0_MASK); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_NS1_Q0: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting IDT24x_REG_NS2_Q0_15_8 (val %u @ 0x%x)", + __func__, (chip->divs.ns2_q0 >> 8) & 0xFF, + IDT24x_REG_NS2_Q0_15_8); + err = i2cwrite( + client, chip->regmap, IDT24x_REG_NS2_Q0_15_8, + (chip->divs.ns2_q0 >> 8) & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_NS2_Q0_15_8: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting IDT24x_REG_NS2_Q0_7_0 (val %u @ 0x%x)", + __func__, chip->divs.ns2_q0 & 0xFF, + IDT24x_REG_NS2_Q0_7_0); + err = i2cwrite( + client, chip->regmap, IDT24x_REG_NS2_Q0_7_0, + chip->divs.ns2_q0 & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting IDT24x_REG_NS2_Q0_7_0: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: calling idt24x_enable_output for Q0. requestedFreq: %u", + __func__, chip->clk[0].requested); + idt24x_enable_output(chip, 0, chip->clk[0].requested != 0); + + dev_dbg(&client->dev, + "%s: writing values for q1-q3", __func__); + for (x = 1; x < NUM_OUTPUTS; x++) { + struct clk_register_offsets offsets; + + if (chip->clk[x].requested != 0) { + dev_dbg(&client->dev, + "%s: calling idt24x_get_offsets for %u", + __func__, x); + err = idt24x_get_offsets(x, &offsets); + if (err) { + dev_err(&client->dev, + "%s: error calling idt24x_get_offsets: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: (q%u, nint: %u, nfrac: %u)", + __func__, x, chip->divs.nint[x - 1], + chip->divs.nfrac[x - 1]); + + dev_dbg(&client->dev, + "%s: setting n_17_16_offset (q%u, val %u @ 0x%x)", + __func__, x, + chip->divs.nint[x - 1] >> 16, + offsets.n_17_16_offset); + err = i2cwritewithmask( + client, chip->regmap, offsets.n_17_16_offset, + (chip->divs.nint[x - 1] >> 16) & + offsets.n_17_16_mask, + chip->reg_n_qx_17_16[x - 1], + offsets.n_17_16_mask); + if (err) { + dev_err(&client->dev, + "%s: error setting n_17_16_offset: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting n_15_8_offset (q%u, val %u @ 0x%x)", + __func__, x, + (chip->divs.nint[x - 1] >> 8) & 0xFF, + offsets.n_15_8_offset); + err = i2cwrite( + client, chip->regmap, offsets.n_15_8_offset, + (chip->divs.nint[x - 1] >> 8) & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting n_15_8_offset: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting n_7_0_offset (q%u, val %u @ 0x%x)", + __func__, x, + chip->divs.nint[x - 1] & 0xFF, + offsets.n_7_0_offset); + err = i2cwrite( + client, chip->regmap, offsets.n_7_0_offset, + chip->divs.nint[x - 1] & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting n_7_0_offset: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting nfrac_27_24_offset (q%u, val %u @ 0x%x)", + __func__, x, + (chip->divs.nfrac[x - 1] >> 24), + offsets.nfrac_27_24_offset); + err = i2cwritewithmask( + client, chip->regmap, + offsets.nfrac_27_24_offset, + (chip->divs.nfrac[x - 1] >> 24) & + offsets.nfrac_27_24_mask, + chip->reg_nfrac_qx_27_24[x - 1], + offsets.nfrac_27_24_mask); + if (err) { + dev_err(&client->dev, + "%s: error setting nfrac_27_24_offset: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting nfrac_23_16_offset (q%u, val %u @ 0x%x)", + __func__, x, + (chip->divs.nfrac[x - 1] >> 16) & 0xFF, + offsets.nfrac_23_16_offset); + err = i2cwrite( + client, chip->regmap, + offsets.nfrac_23_16_offset, + (chip->divs.nfrac[x - 1] >> 16) & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting nfrac_23_16_offset: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting nfrac_15_8_offset (q%u, val %u @ 0x%x)", + __func__, x, + (chip->divs.nfrac[x - 1] >> 8) & 0xFF, + offsets.nfrac_15_8_offset); + err = i2cwrite( + client, chip->regmap, + offsets.nfrac_15_8_offset, + (chip->divs.nfrac[x - 1] >> 8) & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting nfrac_15_8_offset: %i", + __func__, err); + return err; + } + + dev_dbg(&client->dev, + "%s: setting nfrac_7_0_offset (q%u, val %u @ 0x%x)", + __func__, x, + chip->divs.nfrac[x - 1] & 0xFF, + offsets.nfrac_7_0_offset); + err = i2cwrite( + client, chip->regmap, offsets.nfrac_7_0_offset, + chip->divs.nfrac[x - 1] & 0xFF); + if (err) { + dev_err(&client->dev, + "%s: error setting nfrac_7_0_offset: %i", + __func__, err); + return err; + } + } + idt24x_enable_output(chip, x, + chip->clk[x].requested != 0); + chip->clk[x].actual = chip->clk[x].requested; + } + return 0; +} + +/** + * idt24x_set_frequency - Adjust output frequency on the attached chip. + * @chip: Device data structure, including all requested frequencies. + * + * Return: 0 on success. + */ +int idt24x_set_frequency(struct clk_idt24x_chip *chip) +{ + int err; + struct i2c_client *client = chip->i2c_client; + int x; + bool all_disabled = true; + + for (x = 0; x < NUM_OUTPUTS; x++) { + if (chip->clk[x].requested == 0) { + idt24x_enable_output(chip, x, false); + chip->clk[x].actual = 0; + } else { + all_disabled = false; + } + } + + if (all_disabled) + /* + * no requested frequencies, so nothing else to calculate + * or write to the chip. If the consumer wants to disable + * all outputs, they can request 0 for all frequencies. + */ + return 0; + + if (chip->input_clk_freq == 0) { + dev_err(&client->dev, + "%s: no input frequency; can't continue.", __func__); + return -EINVAL; + } + + err = idt24x_calc_divs(chip); + if (err) { + dev_err(&client->dev, + "%s: error calling idt24x_calc_divs: %i", + __func__, err); + return err; + } + + err = idt24x_update_device(chip); + if (err) { + dev_err(&client->dev, + "%s: error updating the device: %i", + __func__, err); + return err; + } + + return 0; +} --- linux-xilinx-6.8.0.orig/drivers/clk/idt/clk-idt8t49n24x-core.h +++ linux-xilinx-6.8.0/drivers/clk/idt/clk-idt8t49n24x-core.h @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* clk-idt8t49n24x-core.h - Program 8T49N24x settings via I2C (common code) + * + * Copyright (C) 2018, Integrated Device Technology, Inc. + * + * See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html + * This program is distributed "AS IS" and WITHOUT ANY WARRANTY; + * including the implied warranties of MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, or NON-INFRINGEMENT. + */ + +#ifndef __IDT_CLK_IDT8T49N24X_CORE_H_ +#define __IDT_CLK_IDT8T49N24X_CORE_H_ + +#include +#include +#include + +/* + * The configurations in the settings file have 0x317 registers (last offset + * is 0x316). + */ +#define NUM_CONFIG_REGISTERS 0x317 +#define NUM_INPUTS 2 +#define NUM_OUTPUTS 4 +#define DEBUGFS_BUFFER_LENGTH 200 +#define WRITE_BLOCK_SIZE 32 + +/* Non output-specific registers */ +#define IDT24x_REG_DBL_DIS 0x6C +#define IDT24x_REG_DBL_DIS_MASK 0x01 +#define IDT24x_REG_DSM_INT_8 0x25 +#define IDT24x_REG_DSM_INT_8_MASK 0x01 +#define IDT24x_REG_DSM_INT_7_0 0x26 +#define IDT24x_REG_DSMFRAC_20_16 0x28 +#define IDT24x_REG_DSMFRAC_20_16_MASK 0x1F +#define IDT24x_REG_DSMFRAC_15_8 0x29 +#define IDT24x_REG_DSMFRAC_7_0 0x2A +#define IDT24x_REG_OUTEN 0x39 +#define IDT24x_REG_OUTMODE0_1 0x3E +#define IDT24x_REG_OUTMODE2_3 0x3D +#define IDT24x_REG_Q_DIS 0x6F + +/* Q0 */ +#define IDT24x_REG_OUTEN0_MASK 0x01 +#define IDT24x_REG_OUTMODE0_MASK 0x0E +#define IDT24x_REG_Q0_DIS_MASK 0x01 +#define IDT24x_REG_NS1_Q0 0x3F +#define IDT24x_REG_NS1_Q0_MASK 0x03 +#define IDT24x_REG_NS2_Q0_15_8 0x40 +#define IDT24x_REG_NS2_Q0_7_0 0x41 + +/* Q1 */ +#define IDT24x_REG_OUTEN1_MASK 0x02 +#define IDT24x_REG_OUTMODE1_MASK 0xE0 +#define IDT24x_REG_Q1_DIS_MASK 0x02 +#define IDT24x_REG_N_Q1_17_16 0x42 +#define IDT24x_REG_N_Q1_17_16_MASK 0x03 +#define IDT24x_REG_N_Q1_15_8 0x43 +#define IDT24x_REG_N_Q1_7_0 0x44 +#define IDT24x_REG_NFRAC_Q1_27_24 0x57 +#define IDT24x_REG_NFRAC_Q1_27_24_MASK 0x0F +#define IDT24x_REG_NFRAC_Q1_23_16 0x58 +#define IDT24x_REG_NFRAC_Q1_15_8 0x59 +#define IDT24x_REG_NFRAC_Q1_7_0 0x5A + +/* Q2 */ +#define IDT24x_REG_OUTEN2_MASK 0x04 +#define IDT24x_REG_OUTMODE2_MASK 0x0E +#define IDT24x_REG_Q2_DIS_MASK 0x04 +#define IDT24x_REG_N_Q2_17_16 0x45 +#define IDT24x_REG_N_Q2_17_16_MASK 0x03 +#define IDT24x_REG_N_Q2_15_8 0x46 +#define IDT24x_REG_N_Q2_7_0 0x47 +#define IDT24x_REG_NFRAC_Q2_27_24 0x5B +#define IDT24x_REG_NFRAC_Q2_27_24_MASK 0x0F +#define IDT24x_REG_NFRAC_Q2_23_16 0x5C +#define IDT24x_REG_NFRAC_Q2_15_8 0x5D +#define IDT24x_REG_NFRAC_Q2_7_0 0x5E + +/* Q3 */ +#define IDT24x_REG_OUTEN3_MASK 0x08 +#define IDT24x_REG_OUTMODE3_MASK 0xE0 +#define IDT24x_REG_Q3_DIS_MASK 0x08 +#define IDT24x_REG_N_Q3_17_16 0x48 +#define IDT24x_REG_N_Q3_17_16_MASK 0x03 +#define IDT24x_REG_N_Q3_15_8 0x49 +#define IDT24x_REG_N_Q3_7_0 0x4A +#define IDT24x_REG_NFRAC_Q3_27_24 0x5F +#define IDT24x_REG_NFRAC_Q3_27_24_MASK 0x0F +#define IDT24x_REG_NFRAC_Q3_23_16 0x60 +#define IDT24x_REG_NFRAC_Q3_15_8 0x61 +#define IDT24x_REG_NFRAC_Q3_7_0 0x62 + +/** + * struct idt24x_output - device output information + * @hw: hw registration info for this specific output clcok. This gets + * passed as an argument to CCF api calls (e.g., set_rate). + * container_of can then be used to get the reference to this + * struct. + * @chip: store a reference to the parent device structure. container_of + * cannot be used to get to the parent device structure from + * idt24x_output, because clk_idt24x_chip contains an array of + * output structs (for future enhancements to support devices + * with different numbers of output clocks). + * @index: identifies output on the chip; used in debug statements + * @requested: requested output clock frequency (in Hz) + * @actual: actual output clock frequency (in Hz). Will only be set after + * successful update of the device. + * @debug_freq: stores value for debugfs file. Use this instead of requested + * struct var because debugfs expects u64, not u32. + */ +struct idt24x_output { + struct clk_hw hw; + struct clk_idt24x_chip *chip; + u8 index; + u32 requested; + u32 actual; + u64 debug_freq; +}; + +/** + * struct idt24x_dividers - output dividers + * @dsmint: int component of feedback divider for VCO (2-stage divider) + * @dsmfrac: fractional component of feedback divider for VCO + * @ns1_q0: ns1 divider component for Q0 + * @ns2_q0: ns2 divider component for Q0 + * @nint: int divider component for Q1-3 + * @nfrac: fractional divider component for Q1-3 + */ +struct idt24x_dividers { + u16 dsmint; + u32 dsmfrac; + + u8 ns1_q0; + u16 ns2_q0; + + u32 nint[3]; + u32 nfrac[3]; +}; + +/** + * struct clk_idt24x_chip - device info for chip + * @regmap: register map used to perform i2c writes to the chip + * @i2c_client: i2c_client struct passed to probe + * @min_freq: min frequency for this chip + * @max_freq: max frequency for this chip + * @settings: filled in if full register map is specified in the DT + * @has_settings: true if settings array is valid + * @input_clk: ptr to input clock specified in DT + * @input_clk_num: which input clock was specified. 0-based. A value of + * NUM_INPUTS indicates that a XTAL is used as the input. + * @input_clk_nb: notification support (if input clk changes) + * @input_clk_freq: current freq of input_clk + * @doubler_disabled: whether input doubler is enabled. This value is read + * from the hw on probe (in case it is set in @settings). + * @clk: array of outputs. One entry per output supported by the + * chip. Frequencies requested via the ccf api will be + * recorded in this array. + * @reg_dsm_int_8: record current value from hw to avoid modifying + * when writing register values + * @reg_dsm_frac_20_16: record current value + * @reg_out_en_x: record current value + * @reg_out_mode_0_1: record current value + * @reg_out_mode_2_3: record current value + * @reg_qx_dis: record current value + * @reg_ns1_q0: record current value + * @reg_n_qx_17_16: record current value + * @reg_nfrac_qx_27_24: record current value + * @divs: output divider values for all outputs + * @debugfs_dirroot: debugfs support + * @debugfs_fileaction: debugfs support + * @debugfs_filei2c: debugfs support + * @debugfs_map: debugfs support + * @dbg_cache: debugfs support + * @debugfs_fileqfreq: debugfs support + */ +struct clk_idt24x_chip { + struct regmap *regmap; + struct i2c_client *i2c_client; + + u32 min_freq; + u32 max_freq; + + u8 settings[NUM_CONFIG_REGISTERS]; + + bool has_settings; + + struct clk *input_clk; + int input_clk_num; + struct notifier_block input_clk_nb; + u32 input_clk_freq; + + bool doubler_disabled; + + struct idt24x_output clk[NUM_OUTPUTS]; + + unsigned int reg_dsm_int_8; + unsigned int reg_dsm_frac_20_16; + unsigned int reg_out_en_x; + unsigned int reg_out_mode_0_1; + unsigned int reg_out_mode_2_3; + unsigned int reg_qx_dis; + unsigned int reg_ns1_q0; + unsigned int reg_n_qx_17_16[3]; + unsigned int reg_nfrac_qx_27_24[3]; + + struct idt24x_dividers divs; + + struct dentry *debugfs_dirroot, *debugfs_fileaction, *debugfs_filei2c, + *debugfs_map; + char dbg_cache[DEBUGFS_BUFFER_LENGTH]; + struct dentry *debugfs_fileqfreq[4]; +}; + +#define to_idt24x_output(_hw) \ + container_of(_hw, struct idt24x_output, hw) +#define to_clk_idt24x_from_client(_client) \ + container_of(_client, struct clk_idt24x_chip, i2c_client) +#define to_clk_idt24x_from_nb(_nb) \ + container_of(_nb, struct clk_idt24x_chip, input_clk_nb) + +/** + * struct clk_register_offsets - register offsets for current context + * @oe_offset: offset for current output enable and mode + * @oe_mask: mask for current output enable + * @dis_mask: mask for current output disable + * @n_17_16_offset: offset for current output int divider (bits 17:16) + * @n_17_16_mask: mask for current output int divider (bits 17:16) + * @n_15_8_offset: offset for current output int divider (bits 15:8) + * @n_7_0_offset: offset for current output int divider (bits 7:0) + * @nfrac_27_24_offset: offset for current output frac divider (bits 27:24) + * @nfrac_27_24_mask: mask for current output frac divider (bits 27:24) + * @nfrac_23_16_offset: offset for current output frac divider (bits 23:16) + * @nfrac_15_8_offset: offset for current output frac divider (bits 15:8) + * @nfrac_7_0_offset: offset for current output frac divider (bits 7:0) + * @ns1_offset: offset for stage 1 div for output Q0 + * @ns1_offset_mask: mask for stage 1 div for output Q0 + * @ns2_15_8_offset: offset for stage 2 div for output Q0 (bits 15:8) + * @ns2_7_0_offset: offset for stage 2 div for output Q0 (bits 7:0) + */ +struct clk_register_offsets { + u16 oe_offset; + u8 oe_mask; + u8 dis_mask; + + u16 n_17_16_offset; + u8 n_17_16_mask; + u16 n_15_8_offset; + u16 n_7_0_offset; + u16 nfrac_27_24_offset; + u8 nfrac_27_24_mask; + u16 nfrac_23_16_offset; + u16 nfrac_15_8_offset; + u16 nfrac_7_0_offset; + + u16 ns1_offset; + u8 ns1_offset_mask; + u16 ns2_15_8_offset; + u16 ns2_7_0_offset; +}; + +int bits_to_shift(unsigned int mask); +int i2cwritebulk( + struct i2c_client *client, struct regmap *map, + unsigned int reg, u8 val[], size_t val_count); +int idt24x_get_offsets( + u8 output_num, + struct clk_register_offsets *offsets); +int idt24x_set_frequency(struct clk_idt24x_chip *chip); + +#endif /* __IDT_CLK_IDT8T49N24X_CORE_H_ */ --- linux-xilinx-6.8.0.orig/drivers/clk/idt/clk-idt8t49n24x-debugfs.c +++ linux-xilinx-6.8.0/drivers/clk/idt/clk-idt8t49n24x-debugfs.c @@ -0,0 +1,375 @@ +// SPDX-License-Identifier: GPL-2.0 +/* clk-idt8t49n24x-debugfs.c - Debugfs support for 8T49N24x + * + * Copyright (C) 2018, Integrated Device Technology, Inc. + * + * See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html + * This program is distributed "AS IS" and WITHOUT ANY WARRANTY; + * including the implied warranties of MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, or NON-INFRINGEMENT. + */ + +#include +#include +#include +#include + +#include "clk-idt8t49n24x-debugfs.h" + +static struct clk_idt24x_chip *idt24x_chip_fordebugfs; + +static int idt24x_read_all_settings( + struct clk_idt24x_chip *chip, char *output_buffer, int count) +{ + u8 settings[NUM_CONFIG_REGISTERS]; + int err = 0; + int x; + + err = regmap_bulk_read( + chip->regmap, 0x0, settings, NUM_CONFIG_REGISTERS); + if (!err) { + output_buffer[0] = '\0'; + for (x = 0; x < ARRAY_SIZE(settings); x++) { + char dbg[4]; + + if ((strlen(output_buffer) + 4) > count) + return -EINVAL; + sprintf(dbg, "%02x ", settings[x]); + strcat(output_buffer, dbg); + } + } + return err; +} + +/** + * idt24x_debugfs_writer_action - Write handler for the "action" debugfs file. + * @fp: file pointer + * @user_buffer: buffer of text written to file + * @count: size of text in buffer + * @position: pass in current position, return new position + * + * Return: result of call to simple_write_to_buffer + * + * Use the "action" file as a trigger for setting all requested + * rates. The driver doesn't get any notification when the files + * representing the Qx outputs are written to, so something else is + * needed to notify the driver that the device should be udpated. + * + * It doesn't matter what you write to the action debugs file. When the + * handler is called, the device will be updated. + */ +static ssize_t idt24x_debugfs_writer_action( + struct file *fp, const char __user *user_buffer, + size_t count, loff_t *position) +{ + int err = 0; + int x; + u32 freq; + bool needs_update = true; + struct i2c_client *client = idt24x_chip_fordebugfs->i2c_client; + + if (count > DEBUGFS_BUFFER_LENGTH) + return -EINVAL; + + for (x = 0; x < NUM_OUTPUTS; x++) { + freq = idt24x_chip_fordebugfs->clk[x].debug_freq; + if (freq) { + needs_update = false; + dev_dbg(&client->dev, + "%s: calling clk_set_rate with debug frequency for Q%i", + __func__, x); + err = clk_set_rate( + idt24x_chip_fordebugfs->clk[x].hw.clk, freq); + if (err) { + dev_err(&client->dev, + "error calling clk_set_rate for Q%i (%i)\n", + x, err); + } + } else { + needs_update = true; + idt24x_chip_fordebugfs->clk[x].requested = 0; + dev_dbg(&client->dev, + "%s: debug frequency for Q%i not set; make sure clock is disabled", + __func__, x); + } + } + + if (needs_update) { + dev_dbg(&client->dev, + "%s: calling idt24x_set_frequency to ensure any clocks that should be disabled are turned off.", + __func__); + err = idt24x_set_frequency(idt24x_chip_fordebugfs); + if (err) { + dev_err(&idt24x_chip_fordebugfs->i2c_client->dev, + "%s: error calling idt24x_set_frequency (%i)\n", + __func__, err); + return err; + } + } + + return simple_write_to_buffer( + idt24x_chip_fordebugfs->dbg_cache, DEBUGFS_BUFFER_LENGTH, + position, user_buffer, count); +} + +/** + * idt24x_debugfs_reader_action - Read the "action" debugfs file. + * @fp: file pointer + * @user_buffer: buffer of text written to file + * @count: size of text in buffer + * @position: pass in current position, return new position + * + * Return: whatever was last written to the "action" debugfs file. + */ +static ssize_t idt24x_debugfs_reader_action( + struct file *fp, char __user *user_buffer, size_t count, + loff_t *position) +{ + return simple_read_from_buffer( + user_buffer, count, position, idt24x_chip_fordebugfs->dbg_cache, + DEBUGFS_BUFFER_LENGTH); +} + +/** + * idt24x_debugfs_reader_map - display the current registers on the device + * @fp: file pointer + * @user_buffer: buffer of text written to file + * @count: size of text in buffer + * @position: pass in current position, return new position + * + * Reads the current register map from the attached chip via I2C and + * returns it. + * + * Return: result of call to simple_read_from_buffer + */ +static ssize_t idt24x_debugfs_reader_map( + struct file *fp, char __user *user_buffer, size_t count, + loff_t *position) +{ + int err = 0; + char *buf = kzalloc(5000, GFP_KERNEL); + + dev_dbg(&idt24x_chip_fordebugfs->i2c_client->dev, + "calling idt24x_read_all_settings (count: %zu)\n", count); + err = idt24x_read_all_settings(idt24x_chip_fordebugfs, buf, 5000); + if (err) { + dev_err(&idt24x_chip_fordebugfs->i2c_client->dev, + "error calling idt24x_read_all_settings (%i)\n", err); + return 0; + } + /* TMGCDR-1456. We're returning 1 byte too few. */ + err = simple_read_from_buffer( + user_buffer, count, position, buf, strlen(buf)); + kfree(buf); + return err; +} + +/** + * idt24x_handle_i2c_debug_token - process "token" written to the i2c file + * @dev: pointer to device structure + * @token: pointer to current char being examined + * @reg: pass in current register, or return register from token. + * @val: resulting array of bytes being parsed + * @nextbyte: position in val array to store next byte + * + * Utility function to operate on the current "token" (from within a + * space-delimited string) written to the i2c debugfs file. It will + * either be a register offset or a byte to be added to the val array. + * If it is added to the val array, auto-increment nextbyte. + * + * Return: 0 for success + */ +static int idt24x_handle_i2c_debug_token( + const struct device *dev, char *token, unsigned int *reg, + u8 val[], u16 *nextbyte) +{ + int err = 0; + + dev_dbg(dev, "got token (%s)\n", token); + if (*reg == -1) { + err = kstrtouint(token, 16, reg); + if (!err) + dev_dbg(dev, "hex register address == 0x%x\n", *reg); + } else { + u8 temp; + + err = kstrtou8(token, 16, &temp); + if (!err) { + dev_dbg(dev, "data byte == 0x%x\n", temp); + val[*nextbyte] = temp; + *nextbyte += 1; + } + } + if (err == -ERANGE) + dev_err(dev, "ERANGE error when parsing data\n"); + else if (err == -EINVAL) + dev_err(dev, "EINVAL error when parsing data\n"); + else if (err) + dev_err(dev, "error when parsing data: %i\n", err); + return err; +} + +/** + * idt24x_debugfs_writer_i2c - debugfs handler for i2c file + * @fp: file pointer + * @user_buffer: buffer of text written to file + * @count: size of text in buffer + * @position: pass in current position, return new position + * + * Handler for the "i2c" debugfs file. Write to this file to write bytes + * via I2C to a particular offset. + * + * Usage: echo 006c 01 02 0D FF > i2c + * + * First 4 chars are the 2-byte i2c register offset. Then follow that + * with a sequence of 2-char bytes in hex format that you want to write + * starting at that offset. + * + * Return: result of simple_write_to_buffer + */ +static ssize_t idt24x_debugfs_writer_i2c(struct file *fp, + const char __user *user_buffer, + size_t count, loff_t *position) +{ + int err = 0; + int x = 0; + int start = 0; + ssize_t written; + unsigned int reg = -1; + u8 val[WRITE_BLOCK_SIZE]; + u16 nextbyte = 0; + char token[16]; + + if (count > DEBUGFS_BUFFER_LENGTH) + return -EINVAL; + + written = simple_write_to_buffer( + idt24x_chip_fordebugfs->dbg_cache, DEBUGFS_BUFFER_LENGTH, + position, user_buffer, count); + if (written != count) { + dev_dbg(&idt24x_chip_fordebugfs->i2c_client->dev, + "write count != expected count"); + return written; + } + + for (x = 0; x < count; x++) { + token[x - start] = idt24x_chip_fordebugfs->dbg_cache[x]; + if (idt24x_chip_fordebugfs->dbg_cache[x] == ' ') { + token[x - start] = '\0'; + err = idt24x_handle_i2c_debug_token( + &idt24x_chip_fordebugfs->i2c_client->dev, + token, ®, val, &nextbyte); + if (err) + break; + start = x + 1; + } + } + + /* handle the last token */ + if (!err) { + token[count - start] = '\0'; + err = idt24x_handle_i2c_debug_token( + &idt24x_chip_fordebugfs->i2c_client->dev, token, ®, + val, &nextbyte); + } + + if (!err && reg != -1 && nextbyte > 0) { + err = i2cwritebulk( + idt24x_chip_fordebugfs->i2c_client, + idt24x_chip_fordebugfs->regmap, + reg, val, nextbyte); + if (err) { + dev_err(&idt24x_chip_fordebugfs->i2c_client->dev, + "error writing data chip (%i)\n", err); + return err; + } + dev_dbg(&idt24x_chip_fordebugfs->i2c_client->dev, + "successfully wrote i2c data to chip"); + } + + return written; +} + +static const struct file_operations idt24x_fops_debug_action = { + .read = idt24x_debugfs_reader_action, + .write = idt24x_debugfs_writer_action, +}; + +static const struct file_operations idt24x_fops_debug_map = { + .read = idt24x_debugfs_reader_map +}; + +static const struct file_operations idt24x_fops_debug_i2c = { + .write = idt24x_debugfs_writer_i2c, +}; + +/** + * idt24x_expose_via_debugfs - Set up all debugfs files + * @client: pointer to i2c_client structure + * @chip: Device data structure + * + * Sets up all debugfs files to use for debugging the driver. + * Return: error code. 0 if success or debugfs doesn't appear to be enabled. + */ +int idt24x_expose_via_debugfs(struct i2c_client *client, + struct clk_idt24x_chip *chip) +{ + int output_num; + + /* + * create root directory in /sys/kernel/debugfs + */ + chip->debugfs_dirroot = debugfs_create_dir("idt24x", NULL); + if (!chip->debugfs_dirroot) { + /* debugfs probably not enabled. Don't fail the probe. */ + return 0; + } + + /* + * create files in the root directory. This requires read and + * write file operations + */ + chip->debugfs_fileaction = debugfs_create_file( + "action", 0644, chip->debugfs_dirroot, NULL, + &idt24x_fops_debug_action); + if (!chip->debugfs_fileaction) { + dev_err(&client->dev, + "%s: error creating action file", __func__); + return (-ENODEV); + } + + chip->debugfs_map = debugfs_create_file( + "map", 0444, chip->debugfs_dirroot, NULL, + &idt24x_fops_debug_map); + if (!chip->debugfs_map) { + dev_err(&client->dev, + "%s: error creating map file", __func__); + return (-ENODEV); + } + + for (output_num = 0; output_num < NUM_OUTPUTS; output_num++) { + char name[5]; + + sprintf(name, "q%d", output_num); + debugfs_create_u64(name, 0644, chip->debugfs_dirroot, + &chip->clk[output_num].debug_freq); + } + + chip->debugfs_filei2c = debugfs_create_file( + "i2c", 0644, chip->debugfs_dirroot, NULL, + &idt24x_fops_debug_i2c); + if (!chip->debugfs_filei2c) { + dev_err(&client->dev, + "%s: error creating i2c file", __func__); + return (-ENODEV); + } + + dev_dbg(&client->dev, "%s: success", __func__); + idt24x_chip_fordebugfs = chip; + return 0; +} + +void idt24x_cleanup_debugfs(struct clk_idt24x_chip *chip) +{ + debugfs_remove_recursive(chip->debugfs_dirroot); +} --- linux-xilinx-6.8.0.orig/drivers/clk/idt/clk-idt8t49n24x-debugfs.h +++ linux-xilinx-6.8.0/drivers/clk/idt/clk-idt8t49n24x-debugfs.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* clk-idt8t49n24x-debugfs.h - Debugfs support for 8T49N24x + * + * Copyright (C) 2018, Integrated Device Technology, Inc. + * + * See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html + * This program is distributed "AS IS" and WITHOUT ANY WARRANTY; + * including the implied warranties of MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, or NON-INFRINGEMENT. + */ + +#ifndef __IDT_CLK_IDT8T49N24X_DEBUGFS_H_ +#define __IDT_CLK_IDT8T49N24X_DEBUGFS_H_ + +#include "clk-idt8t49n24x-core.h" + +int idt24x_expose_via_debugfs(struct i2c_client *client, + struct clk_idt24x_chip *chip); +void idt24x_cleanup_debugfs(struct clk_idt24x_chip *chip); + +#endif /* __IDT_CLK_IDT8T49N24X_DEBUGFS_H_*/ --- linux-xilinx-6.8.0.orig/drivers/clk/idt/clk-idt8t49n24x.c +++ linux-xilinx-6.8.0/drivers/clk/idt/clk-idt8t49n24x.c @@ -0,0 +1,638 @@ +// SPDX-License-Identifier: GPL-2.0 +/* clk-idt8t49n24x.c - Program 8T49N24x settings via I2C. + * + * Copyright (C) 2018, Integrated Device Technology, Inc. + * + * See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html + * This program is distributed "AS IS" and WITHOUT ANY WARRANTY; + * including the implied warranties of MERCHANTABILITY, FITNESS FOR + * A PARTICULAR PURPOSE, or NON-INFRINGEMENT. + */ + +#include +#include +#include + +#include "clk-idt8t49n24x-core.h" +#include "clk-idt8t49n24x-debugfs.h" + +#define OUTPUTMODE_HIGHZ 0 +#define OUTPUTMODE_LVDS 2 +#define IDT24x_MIN_FREQ 1000000L +#define IDT24x_MAX_FREQ 300000000L +#define DRV_NAME "idt8t49n24x" + +enum clk_idt24x_variant { + idt24x +}; + +static u32 mask_and_shift(u32 value, u8 mask) +{ + value &= mask; + return value >> bits_to_shift(mask); +} + +/** + * idt24x_set_output_mode - Set the mode for a particular clock + * output in the register. + * @reg: The current register value before setting the mode. + * @mask: The bitmask identifying where in the register the + * output mode is stored. + * @mode: The mode to set. + * + * Return: the new register value with the specified mode bits set. + */ +static int idt24x_set_output_mode(u32 reg, u8 mask, u8 mode) +{ + if (((reg & mask) >> bits_to_shift(mask)) == OUTPUTMODE_HIGHZ) { + reg = reg & ~mask; + reg |= (OUTPUTMODE_LVDS << bits_to_shift(mask)); + } + return reg; +} + +/** + * idt24x_read_from_hw - Get the current values on the hw + * @chip: Device data structure + * + * Return: 0 on success, negative errno otherwise. + */ +static int idt24x_read_from_hw(struct clk_idt24x_chip *chip) +{ + int err; + struct i2c_client *client = chip->i2c_client; + u32 tmp, tmp2; + u8 output; + + err = regmap_read(chip->regmap, IDT24x_REG_DSM_INT_8, + &chip->reg_dsm_int_8); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_DSM_INT_8: %i", + __func__, err); + return err; + } + dev_dbg(&client->dev, "%s: reg_dsm_int_8: 0x%x", + __func__, chip->reg_dsm_int_8); + + err = regmap_read(chip->regmap, IDT24x_REG_DSMFRAC_20_16_MASK, + &chip->reg_dsm_frac_20_16); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_DSMFRAC_20_16_MASK: %i", + __func__, err); + return err; + } + dev_dbg(&client->dev, "%s: reg_dsm_frac_20_16: 0x%x", + __func__, chip->reg_dsm_frac_20_16); + + err = regmap_read(chip->regmap, IDT24x_REG_OUTEN, &chip->reg_out_en_x); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_OUTEN: %i", + __func__, err); + return err; + } + dev_dbg(&client->dev, "%s: reg_out_en_x: 0x%x", + __func__, chip->reg_out_en_x); + + err = regmap_read(chip->regmap, IDT24x_REG_OUTMODE0_1, &tmp); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_OUTMODE0_1: %i", + __func__, err); + return err; + } + + tmp2 = idt24x_set_output_mode( + tmp, IDT24x_REG_OUTMODE0_MASK, OUTPUTMODE_LVDS); + tmp2 = idt24x_set_output_mode( + tmp2, IDT24x_REG_OUTMODE1_MASK, OUTPUTMODE_LVDS); + dev_dbg(&client->dev, + "%s: reg_out_mode_0_1 original: 0x%x. After setting OUT0/1 to LVDS if necessary: 0x%x", + __func__, tmp, tmp2); + chip->reg_out_mode_0_1 = tmp2; + + err = regmap_read(chip->regmap, IDT24x_REG_OUTMODE2_3, &tmp); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_OUTMODE2_3: %i", + __func__, err); + return err; + } + + tmp2 = idt24x_set_output_mode( + tmp, IDT24x_REG_OUTMODE2_MASK, OUTPUTMODE_LVDS); + tmp2 = idt24x_set_output_mode( + tmp2, IDT24x_REG_OUTMODE3_MASK, OUTPUTMODE_LVDS); + dev_dbg(&client->dev, + "%s: reg_out_mode_2_3 original: 0x%x. After setting OUT2/3 to LVDS if necessary: 0x%x", + __func__, tmp, tmp2); + chip->reg_out_mode_2_3 = tmp2; + + err = regmap_read(chip->regmap, IDT24x_REG_Q_DIS, &chip->reg_qx_dis); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_Q_DIS: %i", + __func__, err); + return err; + } + dev_dbg(&client->dev, "%s: reg_qx_dis: 0x%x", + __func__, chip->reg_qx_dis); + + err = regmap_read(chip->regmap, IDT24x_REG_NS1_Q0, &chip->reg_ns1_q0); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_NS1_Q0: %i", + __func__, err); + return err; + } + dev_dbg(&client->dev, "%s: reg_ns1_q0: 0x%x", + __func__, chip->reg_ns1_q0); + + for (output = 1; output <= 3; output++) { + struct clk_register_offsets offsets; + + err = idt24x_get_offsets(output, &offsets); + if (err) { + dev_err(&client->dev, + "%s: error calling idt24x_get_offsets: %i", + __func__, err); + return err; + } + + err = regmap_read(chip->regmap, offsets.n_17_16_offset, + &chip->reg_n_qx_17_16[output - 1]); + if (err) { + dev_err(&client->dev, + "%s: error reading n_17_16_offset for output %d (offset: 0x%x): %i", + __func__, output, offsets.n_17_16_offset, err); + return err; + } + dev_dbg(&client->dev, + "%s: reg_n_qx_17_16[Q%u]: 0x%x", + __func__, output, chip->reg_n_qx_17_16[output - 1]); + + err = regmap_read(chip->regmap, offsets.nfrac_27_24_offset, + &chip->reg_nfrac_qx_27_24[output - 1]); + if (err) { + dev_err(&client->dev, + "%s: error reading nfrac_27_24_offset for output %d (offset: 0x%x): %i", + __func__, output, + offsets.nfrac_27_24_offset, err); + return err; + } + dev_dbg(&client->dev, + "%s: reg_nfrac_qx_27_24[Q%u]: 0x%x", + __func__, output, + chip->reg_nfrac_qx_27_24[output - 1]); + } + + dev_info(&client->dev, + "%s: initial values read from chip successfully", + __func__); + + /* Also read DBL_DIS to determine whether the doubler is disabled. */ + err = regmap_read(chip->regmap, IDT24x_REG_DBL_DIS, &tmp); + if (err) { + dev_err(&client->dev, + "%s: error reading IDT24x_REG_DBL_DIS: %i", + __func__, err); + return err; + } + chip->doubler_disabled = mask_and_shift(tmp, IDT24x_REG_DBL_DIS_MASK); + dev_dbg(&client->dev, "%s: doubler_disabled: %d", + __func__, chip->doubler_disabled); + + return 0; +} + +/** + * idt24x_set_rate - Sets the specified output clock to the specified rate. + * @hw: clk_hw struct that identifies the specific output clock. + * @rate: the rate (in Hz) for the specified clock. + * @parent_rate:(not sure) the rate for a parent signal (e.g., + * the VCO feeding the output) + * + * This function will call idt24_set_frequency, which means it will + * calculate divider for all requested outputs and update the attached + * device (issue I2C commands to update the registers). + * + * Return: 0 on success. + */ +static int idt24x_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + int err = 0; + + /* + * hw->clk is the pointer to the specific output clock the user is + * requesting. We use hw to get back to the output structure for + * the output clock. Set the requested rate in the output structure. + * Note that container_of cannot be used to find the device structure + * (clk_idt24x_chip) from clk_hw, because clk_idt24x_chip has an array + * of idt24x_output structs. That is why it is necessary to use + * output->chip to access the device structure. + */ + struct idt24x_output *output = to_idt24x_output(hw); + struct i2c_client *client = output->chip->i2c_client; + + if (rate < output->chip->min_freq || rate > output->chip->max_freq) { + dev_err(&client->dev, + "requested frequency (%luHz) is out of range\n", rate); + return -EINVAL; + } + + /* + * Set the requested frequency in the output data structure, and then + * call idt24x_set_frequency. idt24x_set_frequency considers all + * requested frequencies when deciding on a vco frequency and + * calculating dividers. + */ + output->requested = rate; + + /* + * Also set in the memory location used by the debugfs file + * that exposes the output clock frequency. That allows querying + * the current rate via debugfs. + */ + output->debug_freq = rate; + + dev_info(&client->dev, + "%s. calling idt24x_set_frequency for Q%u. rate: %lu", + __func__, output->index, rate); + err = idt24x_set_frequency(output->chip); + + if (err != 0) + dev_err(&client->dev, "error calling set_frequency: %d", err); + + return err; +} + +/** + * idt24x_round_rate - get valid rate that is closest to the requested rate + * @hw: clk_hw struct that identifies the specific output clock. + * @rate: the rate (in Hz) for the specified clock. + * @parent_rate:(not sure) the rate for a parent signal (e.g., the VCO + * feeding the output). This is an i/o param. + * If the driver supports a parent clock for the output (e.g., + * the VCO(?), then set this param to indicate what the rate of + * the parent would be (e.g., the VCO frequency) if the rounded + * rate is used. + * + * Returns the closest rate to the requested rate actually supported by the + * chip. + * + * Return: adjusted rate + */ +static long idt24x_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + /* + * The chip has fractional output dividers, so assume it + * can provide the requested rate. + * + * TODO: figure out the closest rate that chip can support + * within a low error threshold and return that rate. + */ + return rate; +} + +/** + * idt24x_recalc_rate - return the frequency being provided by the clock. + * @hw: clk_hw struct that identifies the specific output clock. + * @parent_rate: (not sure) the rate for a parent signal (e.g., the + * VCO feeding the output) + * + * This API appears to be used to read the current values from the hardware + * and report the frequency being provided by the clock. Without this function, + * the clock will be initialized to 0 by default. The OS appears to be + * calling this to find out what the current value of the clock is at + * startup, so it can determine when .set_rate is actually changing the + * frequency. + * + * Return: the frequency of the specified clock. + */ +static unsigned long idt24x_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct idt24x_output *output = to_idt24x_output(hw); + + return output->requested; +} + +/* + * Note that .prepare and .unprepare appear to be used more in Gates. + * They do not appear to be necessary for this device. + * Instead, update the device when .set_rate is called. + */ +static const struct clk_ops idt24x_clk_ops = { + .recalc_rate = idt24x_recalc_rate, + .round_rate = idt24x_round_rate, + .set_rate = idt24x_set_rate, +}; + +static bool idt24x_regmap_is_volatile(struct device *dev, unsigned int reg) +{ + return false; +} + +static bool idt24x_regmap_is_writeable(struct device *dev, unsigned int reg) +{ + return true; +} + +static const struct regmap_config idt24x_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .max_register = 0xffff, + .writeable_reg = idt24x_regmap_is_writeable, + .volatile_reg = idt24x_regmap_is_volatile, +}; + +/** + * idt24x_clk_notifier_cb - Clock rate change callback + * @nb: Pointer to notifier block + * @event: Notification reason + * @data: Pointer to notification data object + * + * This function is called when the input clock frequency changes. + * The callback checks whether a valid bus frequency can be generated after the + * change. If so, the change is acknowledged, otherwise the change is aborted. + * New dividers are written to the HW in the pre- or post change notification + * depending on the scaling direction. + * + * Return: NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK + * to acknowledge the change, NOTIFY_DONE if the notification is + * considered irrelevant. + */ +static int idt24x_clk_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct clk_notifier_data *ndata = data; + struct clk_idt24x_chip *chip = to_clk_idt24x_from_nb(nb); + int err = 0; + + dev_info(&chip->i2c_client->dev, + "%s: input frequency changed: %lu Hz. event: %lu", + __func__, ndata->new_rate, event); + + switch (event) { + case PRE_RATE_CHANGE: { + dev_dbg(&chip->i2c_client->dev, "PRE_RATE_CHANGE\n"); + return NOTIFY_OK; + } + case POST_RATE_CHANGE: + chip->input_clk_freq = ndata->new_rate; + /* + * Can't call clock API clk_set_rate here; I believe + * it will be ignored if the rate is the same as we + * set previously. Need to call our internal function. + */ + dev_dbg(&chip->i2c_client->dev, + "POST_RATE_CHANGE. Calling idt24x_set_frequency\n"); + err = idt24x_set_frequency(chip); + if (err) + dev_err(&chip->i2c_client->dev, + "error calling idt24x_set_frequency (%i)\n", + err); + return NOTIFY_OK; + case ABORT_RATE_CHANGE: + return NOTIFY_OK; + default: + return NOTIFY_DONE; + } +} + +static struct clk_hw *of_clk_idt24x_get( + struct of_phandle_args *clkspec, void *_data) +{ + struct clk_idt24x_chip *chip = _data; + unsigned int idx = clkspec->args[0]; + + if (idx >= ARRAY_SIZE(chip->clk)) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &chip->clk[idx].hw; +} + +/** + * idt24x_probe - main entry point for ccf driver + * @client: pointer to i2c_client structure + * + * Main entry point function that gets called to initialize the driver. + * + * Return: 0 for success. + */ +static int idt24x_probe(struct i2c_client *client) +{ + struct clk_idt24x_chip *chip; + struct clk_init_data init; + + int err = 0; + int x; + char buf[6]; + + dev_info(&client->dev, "%s", __func__); + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + init.ops = &idt24x_clk_ops; + init.flags = 0; + init.num_parents = 0; + chip->i2c_client = client; + + chip->min_freq = IDT24x_MIN_FREQ; + chip->max_freq = IDT24x_MAX_FREQ; + + for (x = 0; x < NUM_INPUTS + 1; x++) { + char name[12]; + + sprintf(name, x == NUM_INPUTS ? "input-xtal" : "input-clk%i", + x); + dev_dbg(&client->dev, "attempting to get %s", name); + chip->input_clk = devm_clk_get(&client->dev, name); + if (IS_ERR(chip->input_clk)) { + err = PTR_ERR(chip->input_clk); + /* + * TODO: Handle EPROBE_DEFER error, which indicates + * that the input_clk isn't available now but may be + * later when the appropriate module is loaded. + */ + } else { + err = 0; + chip->input_clk_num = x; + break; + } + } + + if (err) { + dev_err(&client->dev, "Unable to get input clock (%u).", err); + chip->input_clk = NULL; + return err; + } + + chip->input_clk_freq = clk_get_rate(chip->input_clk); + dev_dbg(&client->dev, "Got input-freq from input-clk in device tree: %uHz", + chip->input_clk_freq); + + chip->input_clk_nb.notifier_call = idt24x_clk_notifier_cb; + if (clk_notifier_register(chip->input_clk, &chip->input_clk_nb)) + dev_warn(&client->dev, + "Unable to register clock notifier for input_clk."); + + dev_dbg(&client->dev, "%s: about to read settings: %zu", + __func__, ARRAY_SIZE(chip->settings)); + + err = of_property_read_u8_array( + client->dev.of_node, "settings", chip->settings, + ARRAY_SIZE(chip->settings)); + if (!err) { + dev_dbg(&client->dev, "settings property specified in DT"); + chip->has_settings = true; + } else { + if (err == -EOVERFLOW) { + dev_alert(&client->dev, + "EOVERFLOW error trying to read the settings. ARRAY_SIZE: %zu", + ARRAY_SIZE(chip->settings)); + return err; + } + dev_dbg(&client->dev, + "settings property not specified in DT (or there was an error that can be ignored: %i). The settings property is optional.", + err); + } + + /* + * Requested output frequencies cannot be specified in the DT. + * Either a consumer needs to use the clock API to request the rate, + * or use debugfs to set the rate from user space. Use clock-names in + * DT to specify the output clock. + */ + + chip->regmap = devm_regmap_init_i2c(client, &idt24x_regmap_config); + if (IS_ERR(chip->regmap)) { + dev_err(&client->dev, "failed to allocate register map\n"); + return PTR_ERR(chip->regmap); + } + + dev_dbg(&client->dev, "%s: call i2c_set_clientdata", __func__); + i2c_set_clientdata(client, chip); + + if (chip->has_settings) { + /* + * A raw settings array was specified in the DT. Write the + * settings to the device immediately. + */ + err = i2cwritebulk( + chip->i2c_client, chip->regmap, 0, chip->settings, + ARRAY_SIZE(chip->settings)); + if (err) { + dev_err(&client->dev, + "error writing all settings to chip (%i)\n", + err); + return err; + } + dev_dbg(&client->dev, "successfully wrote full settings array"); + } + + /* + * Whether or not settings were written to the device, read all + * current values from the hw. + */ + dev_dbg(&client->dev, "read from HW"); + err = idt24x_read_from_hw(chip); + if (err) { + dev_err(&client->dev, + "failed calling idt24x_read_from_hw (%i)\n", err); + return err; + } + + /* Create all 4 clocks */ + for (x = 0; x < NUM_OUTPUTS; x++) { + init.name = kasprintf( + GFP_KERNEL, "%s.Q%i", client->dev.of_node->name, x); + chip->clk[x].chip = chip; + chip->clk[x].hw.init = &init; + chip->clk[x].index = x; + err = devm_clk_hw_register(&client->dev, &chip->clk[x].hw); + kfree(init.name); /* clock framework made a copy of the name */ + if (err) { + dev_err(&client->dev, "clock registration failed\n"); + return err; + } + dev_dbg(&client->dev, "successfully registered Q%i", x); + } + + if (err) { + dev_err(&client->dev, "clock registration failed\n"); + return err; + } + + err = of_clk_add_hw_provider( + client->dev.of_node, of_clk_idt24x_get, chip); + if (err) { + dev_err(&client->dev, "unable to add clk provider\n"); + return err; + } + + err = idt24x_expose_via_debugfs(client, chip); + if (err) { + dev_err(&client->dev, + "error calling idt24x_expose_via_debugfs: %i\n", err); + return err; + } + + if (chip->input_clk_num == NUM_INPUTS) + sprintf(buf, "XTAL"); + else + sprintf(buf, "CLK%i", chip->input_clk_num); + dev_info(&client->dev, "probe success. input freq: %uHz (%s), settings string? %s\n", + chip->input_clk_freq, buf, + chip->has_settings ? "true" : "false"); + return 0; +} + +static void idt24x_remove(struct i2c_client *client) +{ + struct clk_idt24x_chip *chip = to_clk_idt24x_from_client(&client); + + dev_info(&client->dev, "%s", __func__); + of_clk_del_provider(client->dev.of_node); + idt24x_cleanup_debugfs(chip); + + if (!chip->input_clk) + clk_notifier_unregister( + chip->input_clk, &chip->input_clk_nb); +} + +static const struct i2c_device_id idt24x_id[] = { + { "idt8t49n24x", idt24x }, + { } +}; +MODULE_DEVICE_TABLE(i2c, idt24x_id); + +static const struct of_device_id idt24x_of_match[] = { + { .compatible = "idt,idt8t49n241" }, + {}, +}; +MODULE_DEVICE_TABLE(of, idt24x_of_match); + +static struct i2c_driver idt24x_driver = { + .driver = { + .name = DRV_NAME, + .of_match_table = idt24x_of_match, + }, + .probe = idt24x_probe, + .remove = idt24x_remove, + .id_table = idt24x_id, +}; + +module_i2c_driver(idt24x_driver); + +MODULE_DESCRIPTION("8T49N24x ccf driver"); +MODULE_AUTHOR("David Cater "); +MODULE_LICENSE("GPL v2"); --- linux-xilinx-6.8.0.orig/drivers/clk/imx/clk-imx8mp-audiomix.c +++ linux-xilinx-6.8.0/drivers/clk/imx/clk-imx8mp-audiomix.c @@ -18,7 +18,12 @@ #define CLKEN0 0x000 #define CLKEN1 0x004 -#define SAI_MCLK_SEL(n) (0x300 + 4 * (n)) /* n in 0..5 */ +#define SAI1_MCLK_SEL 0x300 +#define SAI2_MCLK_SEL 0x304 +#define SAI3_MCLK_SEL 0x308 +#define SAI5_MCLK_SEL 0x30C +#define SAI6_MCLK_SEL 0x310 +#define SAI7_MCLK_SEL 0x314 #define PDM_SEL 0x318 #define SAI_PLL_GNRL_CTL 0x400 @@ -95,13 +100,13 @@ IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK1_SEL, {}, \ clk_imx8mp_audiomix_sai##n##_mclk1_parents, \ ARRAY_SIZE(clk_imx8mp_audiomix_sai##n##_mclk1_parents), \ - SAI_MCLK_SEL(n), 1, 0 \ + SAI##n##_MCLK_SEL, 1, 0 \ }, { \ "sai"__stringify(n)"_mclk2_sel", \ IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK2_SEL, {}, \ clk_imx8mp_audiomix_sai_mclk2_parents, \ ARRAY_SIZE(clk_imx8mp_audiomix_sai_mclk2_parents), \ - SAI_MCLK_SEL(n), 4, 1 \ + SAI##n##_MCLK_SEL, 4, 1 \ }, { \ "sai"__stringify(n)"_ipg_cg", \ IMX8MP_CLK_AUDIOMIX_SAI##n##_IPG, \ --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt7622-apmixedsys.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt7622-apmixedsys.c @@ -127,7 +127,6 @@ of_clk_del_provider(node); mtk_clk_unregister_gates(apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data); mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data); - mtk_free_clk_data(clk_data); } static const struct of_device_id of_match_clk_mt7622_apmixed[] = { --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt7981-topckgen.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt7981-topckgen.c @@ -357,8 +357,9 @@ MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15, 0x1C0, 21), - MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, - 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22), + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, + 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23), /* CLK_CFG_6 */ --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt7988-infracfg.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt7988-infracfg.c @@ -152,7 +152,7 @@ GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1, "infra_pcie_peri_ck_26m_ck_p1", "csw_infra_f26m_sel", 8), GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2, "infra_pcie_peri_ck_26m_ck_p2", - "csw_infra_f26m_sel", 9), + "infra_pcie_peri_ck_26m_ck_p3", 9), GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3, "infra_pcie_peri_ck_26m_ck_p3", "csw_infra_f26m_sel", 10), /* INFRA1 */ --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt8135-apmixedsys.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt8135-apmixedsys.c @@ -59,7 +59,7 @@ ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); if (ret) - return ret; + goto free_clk_data; ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); if (ret) @@ -69,6 +69,8 @@ unregister_plls: mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data); +free_clk_data: + mtk_free_clk_data(clk_data); return ret; } --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt8183-mfgcfg.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt8183-mfgcfg.c @@ -29,6 +29,7 @@ static const struct mtk_clk_desc mfg_desc = { .clks = mfg_clks, .num_clks = ARRAY_SIZE(mfg_clks), + .need_runtime_pm = true, }; static const struct of_device_id of_match_clk_mt8183_mfg[] = { --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt8183.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt8183.c @@ -790,7 +790,7 @@ /* infra_sspm_26m_self is main clock in co-processor, should not be closed in Linux. */ GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self", "f_f26m_ck", 3, CLK_IS_CRITICAL), /* infra_sspm_32k_self is main clock in co-processor, should not be closed in Linux. */ - GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "f_f26m_ck", 4, CLK_IS_CRITICAL), + GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "clk32k", 4, CLK_IS_CRITICAL), GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", "axi_sel", 5), GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", "i2c_sel", 6), GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", "msdc50_hclk_sel", 7), --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mt8365-mm.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mt8365-mm.c @@ -53,7 +53,7 @@ GATE_MM0(CLK_MM_MM_DSI0, "mm_dsi0", "mm_sel", 17), GATE_MM0(CLK_MM_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 18), GATE_MM0(CLK_MM_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 19), - GATE_MM0(CLK_MM_DPI0_DPI0, "mm_dpi0_dpi0", "vpll_dpix", 20), + GATE_MM0(CLK_MM_DPI0_DPI0, "mm_dpi0_dpi0", "dpi0_sel", 20), GATE_MM0(CLK_MM_MM_FAKE, "mm_fake", "mm_sel", 21), GATE_MM0(CLK_MM_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 22), GATE_MM0(CLK_MM_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 23), --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mtk.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mtk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "clk-mtk.h" @@ -494,6 +495,18 @@ return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM; } + + if (mcd->need_runtime_pm) { + devm_pm_runtime_enable(&pdev->dev); + /* + * Do a pm_runtime_resume_and_get() to workaround a possible + * deadlock between clk_register() and the genpd framework. + */ + r = pm_runtime_resume_and_get(&pdev->dev); + if (r) + return r; + } + /* Calculate how many clk_hw_onecell_data entries to allocate */ num_clks = mcd->num_clks + mcd->num_composite_clks; num_clks += mcd->num_fixed_clks + mcd->num_factor_clks; @@ -574,6 +587,9 @@ goto unregister_clks; } + if (mcd->need_runtime_pm) + pm_runtime_put(&pdev->dev); + return r; unregister_clks: @@ -604,6 +620,9 @@ free_base: if (mcd->shared_io && base) iounmap(base); + + if (mcd->need_runtime_pm) + pm_runtime_put(&pdev->dev); return r; } --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-mtk.h +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-mtk.h @@ -237,6 +237,8 @@ int (*clk_notifier_func)(struct device *dev, struct clk *clk); unsigned int mfg_clk_idx; + + bool need_runtime_pm; }; int mtk_clk_pdev_probe(struct platform_device *pdev); --- linux-xilinx-6.8.0.orig/drivers/clk/mediatek/clk-pllfh.c +++ linux-xilinx-6.8.0/drivers/clk/mediatek/clk-pllfh.c @@ -68,7 +68,7 @@ node = of_find_compatible_node(NULL, NULL, compatible_node); if (!node) { - pr_err("cannot find \"%s\"\n", compatible_node); + pr_warn("cannot find \"%s\"\n", compatible_node); return; } --- linux-xilinx-6.8.0.orig/drivers/clk/meson/axg.c +++ linux-xilinx-6.8.0/drivers/clk/meson/axg.c @@ -2142,7 +2142,9 @@ &axg_vclk_input, &axg_vclk2_input, &axg_vclk_div, + &axg_vclk_div1, &axg_vclk2_div, + &axg_vclk2_div1, &axg_vclk_div2_en, &axg_vclk_div4_en, &axg_vclk_div6_en, --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/Kconfig +++ linux-xilinx-6.8.0/drivers/clk/qcom/Kconfig @@ -439,6 +439,7 @@ config SC_CAMCC_8280XP tristate "SC8280XP Camera Clock Controller" + depends on ARM64 || COMPILE_TEST select SC_GCC_8280XP help Support for the camera clock controller on Qualcomm Technologies, Inc @@ -1069,6 +1070,7 @@ config SM_GPUCC_8650 tristate "SM8650 Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST select SM_GCC_8650 help Support for the graphics clock controller on SM8650 devices. --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/apss-ipq-pll.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/apss-ipq-pll.c @@ -55,6 +55,29 @@ }, }; +static struct clk_alpha_pll ipq_pll_stromer = { + .offset = 0x0, + /* + * Reuse CLK_ALPHA_PLL_TYPE_STROMER_PLUS register offsets. + * Although this is a bit confusing, but the offset values + * are correct nevertheless. + */ + .regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS], + .flags = SUPPORTS_DYNAMIC_UPDATE, + .clkr = { + .enable_reg = 0x0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "a53pll", + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_stromer_ops, + }, + }, +}; + static struct clk_alpha_pll ipq_pll_stromer_plus = { .offset = 0x0, .regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS], @@ -73,10 +96,10 @@ }, }; +/* 1.008 GHz configuration */ static const struct alpha_pll_config ipq5018_pll_config = { - .l = 0x32, + .l = 0x2a, .config_ctl_val = 0x4001075b, - .config_ctl_hi_val = 0x304, .main_output_mask = BIT(0), .aux_output_mask = BIT(1), .early_output_mask = BIT(3), @@ -90,7 +113,6 @@ static const struct alpha_pll_config ipq5332_pll_config = { .l = 0x2d, .config_ctl_val = 0x4001075b, - .config_ctl_hi_val = 0x304, .main_output_mask = BIT(0), .aux_output_mask = BIT(1), .early_output_mask = BIT(3), @@ -144,8 +166,8 @@ }; static const struct apss_pll_data ipq5018_pll_data = { - .pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS, - .pll = &ipq_pll_stromer_plus, + .pll_type = CLK_ALPHA_PLL_TYPE_STROMER, + .pll = &ipq_pll_stromer, .pll_config = &ipq5018_pll_config, }; @@ -203,7 +225,8 @@ if (data->pll_type == CLK_ALPHA_PLL_TYPE_HUAYRA) clk_alpha_pll_configure(data->pll, regmap, data->pll_config); - else if (data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER_PLUS) + else if (data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER || + data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER_PLUS) clk_stromer_pll_configure(data->pll, regmap, data->pll_config); ret = devm_clk_register_regmap(dev, &data->pll->clkr); --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/camcc-sc8280xp.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/camcc-sc8280xp.c @@ -630,6 +630,7 @@ F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0), F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), F(760000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_bps_clk_src = { @@ -654,6 +655,7 @@ F(320000000, P_CAMCC_PLL7_OUT_ODD, 1, 0, 0), F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_camnoc_axi_clk_src = { @@ -673,6 +675,7 @@ static const struct freq_tbl ftbl_camcc_cci_0_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(37500000, P_CAMCC_PLL0_OUT_EVEN, 16, 0, 0), + { } }; static struct clk_rcg2 camcc_cci_0_clk_src = { @@ -735,6 +738,7 @@ F(19200000, P_BI_TCXO, 1, 0, 0), F(240000000, P_CAMCC_PLL0_OUT_EVEN, 2.5, 0, 0), F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_cphy_rx_clk_src = { @@ -754,6 +758,7 @@ static const struct freq_tbl ftbl_camcc_csi0phytimer_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0), + { } }; static struct clk_rcg2 camcc_csi0phytimer_clk_src = { @@ -818,6 +823,7 @@ F(200000000, P_CAMCC_PLL0_OUT_EVEN, 3, 0, 0), F(300000000, P_CAMCC_PLL0_OUT_MAIN, 4, 0, 0), F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + { } }; static struct clk_rcg2 camcc_fast_ahb_clk_src = { @@ -838,6 +844,7 @@ F(19200000, P_BI_TCXO, 1, 0, 0), F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } }; static struct clk_rcg2 camcc_icp_clk_src = { @@ -860,6 +867,7 @@ F(558000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), F(637000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), F(760000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_0_clk_src = { @@ -883,6 +891,7 @@ F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0), F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_0_csid_clk_src = { @@ -905,6 +914,7 @@ F(558000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), F(637000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), F(760000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_1_clk_src = { @@ -941,6 +951,7 @@ F(558000000, P_CAMCC_PLL5_OUT_EVEN, 1, 0, 0), F(637000000, P_CAMCC_PLL5_OUT_EVEN, 1, 0, 0), F(760000000, P_CAMCC_PLL5_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_2_clk_src = { @@ -962,6 +973,7 @@ F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0), F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_2_csid_clk_src = { @@ -984,6 +996,7 @@ F(558000000, P_CAMCC_PLL6_OUT_EVEN, 1, 0, 0), F(637000000, P_CAMCC_PLL6_OUT_EVEN, 1, 0, 0), F(760000000, P_CAMCC_PLL6_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_3_clk_src = { @@ -1020,6 +1033,7 @@ F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0), F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } }; static struct clk_rcg2 camcc_ife_lite_0_clk_src = { @@ -1140,6 +1154,7 @@ F(475000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), F(520000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), F(600000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_ipe_0_clk_src = { @@ -1163,6 +1178,7 @@ F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0), F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0), F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0), + { } }; static struct clk_rcg2 camcc_jpeg_clk_src = { @@ -1184,6 +1200,7 @@ F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0), F(320000000, P_CAMCC_PLL7_OUT_ODD, 1, 0, 0), F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0), + { } }; static struct clk_rcg2 camcc_lrme_clk_src = { @@ -1204,6 +1221,7 @@ F(19200000, P_BI_TCXO, 1, 0, 0), F(24000000, P_CAMCC_PLL2_OUT_EARLY, 10, 1, 4), F(64000000, P_CAMCC_PLL2_OUT_EARLY, 15, 0, 0), + { } }; static struct clk_rcg2 camcc_mclk0_clk_src = { @@ -1320,6 +1338,7 @@ static const struct freq_tbl ftbl_camcc_sleep_clk_src[] = { F(32000, P_SLEEP_CLK, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_sleep_clk_src = { @@ -1339,6 +1358,7 @@ static const struct freq_tbl ftbl_camcc_slow_ahb_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(80000000, P_CAMCC_PLL7_OUT_EVEN, 6, 0, 0), + { } }; static struct clk_rcg2 camcc_slow_ahb_clk_src = { @@ -1357,6 +1377,7 @@ static const struct freq_tbl ftbl_camcc_xo_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), + { } }; static struct clk_rcg2 camcc_xo_clk_src = { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/clk-alpha-pll.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/clk-alpha-pll.c @@ -212,7 +212,6 @@ [PLL_OFF_USER_CTL] = 0x18, [PLL_OFF_USER_CTL_U] = 0x1c, [PLL_OFF_CONFIG_CTL] = 0x20, - [PLL_OFF_CONFIG_CTL_U] = 0xff, [PLL_OFF_TEST_CTL] = 0x30, [PLL_OFF_TEST_CTL_U] = 0x34, [PLL_OFF_STATUS] = 0x28, @@ -2474,6 +2473,8 @@ rate = alpha_pll_round_rate(rate, prate, &l, &a, ALPHA_REG_BITWIDTH); regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + + a <<= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH; regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> ALPHA_BITWIDTH); @@ -2538,6 +2539,9 @@ regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> ALPHA_BITWIDTH); + regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), + PLL_ALPHA_EN, PLL_ALPHA_EN); + regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL); /* Wait five micro seconds or more */ --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/clk-smd-rpm.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/clk-smd-rpm.c @@ -768,6 +768,7 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8976 = { .clks = msm8976_clks, + .num_clks = ARRAY_SIZE(msm8976_clks), .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks, .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks), }; --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/dispcc-sdm845.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/dispcc-sdm845.c @@ -759,6 +759,8 @@ static struct gdsc mdss_gdsc = { .gdscr = 0x3000, + .en_few_wait_val = 0x6, + .en_rest_wait_val = 0x5, .pd = { .name = "mdss_gdsc", }, --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/dispcc-sm6350.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/dispcc-sm6350.c @@ -221,26 +221,17 @@ }, }; -static const struct freq_tbl ftbl_disp_cc_mdss_dp_link_clk_src[] = { - F(162000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - F(270000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - F(540000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - F(810000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - { } -}; - static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { .cmd_rcgr = 0x10f8, .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, - .freq_tbl = ftbl_disp_cc_mdss_dp_link_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_dp_link_clk_src", .parent_data = disp_cc_parent_data_0, .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/dispcc-sm8450.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/dispcc-sm8450.c @@ -309,26 +309,17 @@ }, }; -static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = { - F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - { } -}; - static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { .cmd_rcgr = 0x819c, .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx0_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -382,13 +373,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx1_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -442,13 +432,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx2_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -502,13 +491,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx3_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/dispcc-sm8550.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/dispcc-sm8550.c @@ -345,26 +345,17 @@ }, }; -static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = { - F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - { } -}; - static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { .cmd_rcgr = 0x8170, .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_7, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx0_link_clk_src", .parent_data = disp_cc_parent_data_7, .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -418,13 +409,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx1_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -478,13 +468,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx2_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -538,13 +527,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(struct clk_init_data) { .name = "disp_cc_mdss_dptx3_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/dispcc-sm8650.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/dispcc-sm8650.c @@ -343,26 +343,17 @@ }, }; -static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = { - F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0), - { } -}; - static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { .cmd_rcgr = 0x8170, .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_7, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(const struct clk_init_data) { .name = "disp_cc_mdss_dptx0_link_clk_src", .parent_data = disp_cc_parent_data_7, .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -416,13 +407,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(const struct clk_init_data) { .name = "disp_cc_mdss_dptx1_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -476,13 +466,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(const struct clk_init_data) { .name = "disp_cc_mdss_dptx2_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -536,13 +525,12 @@ .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_3, - .freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src, .clkr.hw.init = &(const struct clk_init_data) { .name = "disp_cc_mdss_dptx3_link_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/gcc-ipq5018.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/gcc-ipq5018.c @@ -857,6 +857,7 @@ static const struct freq_tbl ftbl_pcie0_aux_clk_src[] = { F(2000000, P_XO, 12, 0, 0), + { } }; static struct clk_rcg2 pcie0_aux_clk_src = { @@ -1099,6 +1100,7 @@ F(100000000, P_GPLL0, 8, 0, 0), F(200000000, P_GPLL0, 4, 0, 0), F(320000000, P_GPLL0, 2.5, 0, 0), + { } }; static struct clk_rcg2 qpic_io_macro_clk_src = { @@ -1194,6 +1196,7 @@ static const struct freq_tbl ftbl_ubi0_core_clk_src[] = { F(850000000, P_UBI32_PLL, 1, 0, 0), F(1000000000, P_UBI32_PLL, 1, 0, 0), + { } }; static struct clk_rcg2 ubi0_core_clk_src = { @@ -1754,7 +1757,7 @@ .halt_check = BRANCH_HALT_DELAY, .halt_bit = 31, .clkr = { - .enable_reg = 0x683190, + .enable_reg = 0x68190, .enable_mask = BIT(0), .hw.init = &(struct clk_init_data) { .name = "gcc_gmac0_sys_clk", @@ -2180,7 +2183,7 @@ }; static struct clk_branch gcc_pcie1_pipe_clk = { - .halt_reg = 8, + .halt_reg = 0x76018, .halt_check = BRANCH_HALT_DELAY, .halt_bit = 31, .clkr = { @@ -3632,7 +3635,7 @@ [GCC_SYSTEM_NOC_BCR] = { 0x26000, 0 }, [GCC_TCSR_BCR] = { 0x28000, 0 }, [GCC_TLMM_BCR] = { 0x34000, 0 }, - [GCC_UBI0_AXI_ARES] = { 0x680}, + [GCC_UBI0_AXI_ARES] = { 0x68010, 0 }, [GCC_UBI0_AHB_ARES] = { 0x68010, 1 }, [GCC_UBI0_NC_AXI_ARES] = { 0x68010, 2 }, [GCC_UBI0_DBG_ARES] = { 0x68010, 3 }, --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/gcc-ipq6018.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/gcc-ipq6018.c @@ -1554,6 +1554,7 @@ static const struct freq_tbl ftbl_pcie_aux_clk_src[] = { F(24000000, P_XO, 1, 0, 0), + { } }; static const struct clk_parent_data gcc_xo_gpll0_core_pi_sleep_clk[] = { @@ -1734,6 +1735,7 @@ F(160000000, P_GPLL0, 5, 0, 0), F(216000000, P_GPLL6, 5, 0, 0), F(308570000, P_GPLL6, 3.5, 0, 0), + { } }; static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/gcc-ipq8074.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/gcc-ipq8074.c @@ -644,6 +644,7 @@ static const struct freq_tbl ftbl_pcie_aux_clk_src[] = { F(19200000, P_XO, 1, 0, 0), + { } }; static const struct clk_parent_data gcc_xo_gpll0_sleep_clk[] = { @@ -795,6 +796,7 @@ F(19200000, P_XO, 1, 0, 0), F(160000000, P_GPLL0, 5, 0, 0), F(308570000, P_GPLL6, 3.5, 0, 0), + { } }; static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/gcc-ipq9574.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/gcc-ipq9574.c @@ -2082,6 +2082,7 @@ static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = { F(150000000, P_GPLL4, 8, 0, 0), F(300000000, P_GPLL4, 4, 0, 0), + { } }; static struct clk_rcg2 sdcc1_ice_core_clk_src = { @@ -2139,9 +2140,10 @@ static struct clk_branch gcc_crypto_axi_clk = { .halt_reg = 0x16010, + .halt_check = BRANCH_HALT_VOTED, .clkr = { - .enable_reg = 0x16010, - .enable_mask = BIT(0), + .enable_reg = 0xb004, + .enable_mask = BIT(15), .hw.init = &(const struct clk_init_data) { .name = "gcc_crypto_axi_clk", .parent_hws = (const struct clk_hw *[]) { @@ -2155,9 +2157,10 @@ static struct clk_branch gcc_crypto_ahb_clk = { .halt_reg = 0x16014, + .halt_check = BRANCH_HALT_VOTED, .clkr = { - .enable_reg = 0x16014, - .enable_mask = BIT(0), + .enable_reg = 0xb004, + .enable_mask = BIT(16), .hw.init = &(const struct clk_init_data) { .name = "gcc_crypto_ahb_clk", .parent_hws = (const struct clk_hw *[]) { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/gcc-sdm845.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/gcc-sdm845.c @@ -4037,3 +4037,4 @@ MODULE_DESCRIPTION("QTI GCC SDM845 Driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:gcc-sdm845"); +MODULE_SOFTDEP("pre: rpmhpd"); --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/gcc-sm6350.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/gcc-sm6350.c @@ -100,8 +100,8 @@ .enable_mask = BIT(6), .hw.init = &(struct clk_init_data){ .name = "gpll6", - .parent_hws = (const struct clk_hw*[]){ - &gpll0.clkr.hw, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, @@ -124,7 +124,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gpll6_out_even", .parent_hws = (const struct clk_hw*[]){ - &gpll0.clkr.hw, + &gpll6.clkr.hw, }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_fabia_ops, @@ -139,8 +139,8 @@ .enable_mask = BIT(7), .hw.init = &(struct clk_init_data){ .name = "gpll7", - .parent_hws = (const struct clk_hw*[]){ - &gpll0.clkr.hw, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/mmcc-apq8084.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/mmcc-apq8084.c @@ -348,6 +348,7 @@ F(333430000, P_MMPLL1, 3.5, 0, 0), F(400000000, P_MMPLL0, 2, 0, 0), F(466800000, P_MMPLL1, 2.5, 0, 0), + { } }; static struct clk_rcg2 mmss_axi_clk_src = { @@ -372,6 +373,7 @@ F(150000000, P_GPLL0, 4, 0, 0), F(228570000, P_MMPLL0, 3.5, 0, 0), F(320000000, P_MMPLL0, 2.5, 0, 0), + { } }; static struct clk_rcg2 ocmemnoc_clk_src = { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/mmcc-msm8974.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/mmcc-msm8974.c @@ -290,6 +290,7 @@ F(291750000, P_MMPLL1, 4, 0, 0), F(400000000, P_MMPLL0, 2, 0, 0), F(466800000, P_MMPLL1, 2.5, 0, 0), + { } }; static struct clk_rcg2 mmss_axi_clk_src = { @@ -314,6 +315,7 @@ F(150000000, P_GPLL0, 4, 0, 0), F(291750000, P_MMPLL1, 4, 0, 0), F(400000000, P_MMPLL0, 2, 0, 0), + { } }; static struct clk_rcg2 ocmemnoc_clk_src = { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/mmcc-msm8998.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/mmcc-msm8998.c @@ -2535,6 +2535,8 @@ static struct gdsc video_top_gdsc = { .gdscr = 0x1024, + .cxcs = (unsigned int []){ 0x1028, 0x1034, 0x1038 }, + .cxc_count = 3, .pd = { .name = "video_top", }, @@ -2543,20 +2545,26 @@ static struct gdsc video_subcore0_gdsc = { .gdscr = 0x1040, + .cxcs = (unsigned int []){ 0x1048 }, + .cxc_count = 1, .pd = { .name = "video_subcore0", }, .parent = &video_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL, }; static struct gdsc video_subcore1_gdsc = { .gdscr = 0x1044, + .cxcs = (unsigned int []){ 0x104c }, + .cxc_count = 1, .pd = { .name = "video_subcore1", }, .parent = &video_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL, }; static struct gdsc mdss_gdsc = { --- linux-xilinx-6.8.0.orig/drivers/clk/qcom/reset.c +++ linux-xilinx-6.8.0/drivers/clk/qcom/reset.c @@ -22,8 +22,8 @@ return 0; } -static int -qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +static int qcom_reset_set_assert(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) { struct qcom_reset_controller *rst; const struct qcom_reset_map *map; @@ -33,21 +33,22 @@ map = &rst->reset_map[id]; mask = map->bitmask ? map->bitmask : BIT(map->bit); - return regmap_update_bits(rst->regmap, map->reg, mask, mask); + regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0); + + /* Read back the register to ensure write completion, ignore the value */ + regmap_read(rst->regmap, map->reg, &mask); + + return 0; } -static int -qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { - struct qcom_reset_controller *rst; - const struct qcom_reset_map *map; - u32 mask; - - rst = to_qcom_reset_controller(rcdev); - map = &rst->reset_map[id]; - mask = map->bitmask ? map->bitmask : BIT(map->bit); + return qcom_reset_set_assert(rcdev, id, true); +} - return regmap_update_bits(rst->regmap, map->reg, mask, 0); +static int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return qcom_reset_set_assert(rcdev, id, false); } const struct reset_control_ops qcom_reset_ops = { --- linux-xilinx-6.8.0.orig/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ linux-xilinx-6.8.0/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -139,7 +139,7 @@ DEF_MOD("avb3", 214, R8A779A0_CLK_S3D2), DEF_MOD("avb4", 215, R8A779A0_CLK_S3D2), DEF_MOD("avb5", 216, R8A779A0_CLK_S3D2), - DEF_MOD("canfd0", 328, R8A779A0_CLK_CANFD), + DEF_MOD("canfd0", 328, R8A779A0_CLK_S3D2), DEF_MOD("csi40", 331, R8A779A0_CLK_CSI0), DEF_MOD("csi41", 400, R8A779A0_CLK_CSI0), DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0), --- linux-xilinx-6.8.0.orig/drivers/clk/renesas/r8a779f0-cpg-mssr.c +++ linux-xilinx-6.8.0/drivers/clk/renesas/r8a779f0-cpg-mssr.c @@ -161,7 +161,7 @@ DEF_MOD("cmt1", 911, R8A779F0_CLK_R), DEF_MOD("cmt2", 912, R8A779F0_CLK_R), DEF_MOD("cmt3", 913, R8A779F0_CLK_R), - DEF_MOD("pfc0", 915, R8A779F0_CLK_CL16M), + DEF_MOD("pfc0", 915, R8A779F0_CLK_CPEX), DEF_MOD("tsc", 919, R8A779F0_CLK_CL16M), DEF_MOD("rswitch2", 1505, R8A779F0_CLK_RSW2), DEF_MOD("ether-serdes", 1506, R8A779F0_CLK_S0D2_HSC), --- linux-xilinx-6.8.0.orig/drivers/clk/renesas/r8a779g0-cpg-mssr.c +++ linux-xilinx-6.8.0/drivers/clk/renesas/r8a779g0-cpg-mssr.c @@ -22,7 +22,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R8A779G0_CLK_R, + LAST_DT_CORE_CLK = R8A779G0_CLK_CP, /* External Input Clocks */ CLK_EXTAL, @@ -141,6 +141,7 @@ DEF_FIXED("svd2_vip", R8A779G0_CLK_SVD2_VIP, CLK_SV_VIP, 2, 1), DEF_FIXED("cbfusa", R8A779G0_CLK_CBFUSA, CLK_EXTAL, 2, 1), DEF_FIXED("cpex", R8A779G0_CLK_CPEX, CLK_EXTAL, 2, 1), + DEF_FIXED("cp", R8A779G0_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("viobus", R8A779G0_CLK_VIOBUS, CLK_VIO, 1, 1), DEF_FIXED("viobusd2", R8A779G0_CLK_VIOBUSD2, CLK_VIO, 2, 1), DEF_FIXED("vcbus", R8A779G0_CLK_VCBUS, CLK_VC, 1, 1), @@ -193,7 +194,7 @@ DEF_MOD("msi4", 622, R8A779G0_CLK_MSO), DEF_MOD("msi5", 623, R8A779G0_CLK_MSO), DEF_MOD("pciec0", 624, R8A779G0_CLK_S0D2_HSC), - DEF_MOD("pscie1", 625, R8A779G0_CLK_S0D2_HSC), + DEF_MOD("pciec1", 625, R8A779G0_CLK_S0D2_HSC), DEF_MOD("pwm", 628, R8A779G0_CLK_SASYNCPERD4), DEF_MOD("rpc-if", 629, R8A779G0_CLK_RPCD2), DEF_MOD("scif0", 702, R8A779G0_CLK_SASYNCPERD4), @@ -232,10 +233,10 @@ DEF_MOD("cmt1", 911, R8A779G0_CLK_R), DEF_MOD("cmt2", 912, R8A779G0_CLK_R), DEF_MOD("cmt3", 913, R8A779G0_CLK_R), - DEF_MOD("pfc0", 915, R8A779G0_CLK_CL16M), - DEF_MOD("pfc1", 916, R8A779G0_CLK_CL16M), - DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M), - DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M), + DEF_MOD("pfc0", 915, R8A779G0_CLK_CP), + DEF_MOD("pfc1", 916, R8A779G0_CLK_CP), + DEF_MOD("pfc2", 917, R8A779G0_CLK_CP), + DEF_MOD("pfc3", 918, R8A779G0_CLK_CP), DEF_MOD("tsc", 919, R8A779G0_CLK_CL16M), DEF_MOD("tsn", 2723, R8A779G0_CLK_S0D4_HSC), DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER), --- linux-xilinx-6.8.0.orig/drivers/clk/renesas/r9a07g043-cpg.c +++ linux-xilinx-6.8.0/drivers/clk/renesas/r9a07g043-cpg.c @@ -138,7 +138,7 @@ DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4), DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi, mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), - DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi, + DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_shdi, mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4), DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4), @@ -265,6 +265,10 @@ 0x5a8, 1), DEF_MOD("tsu_pclk", R9A07G043_TSU_PCLK, R9A07G043_CLK_TSU, 0x5ac, 0), +#ifdef CONFIG_RISCV + DEF_MOD("nceplic_aclk", R9A07G043_NCEPLIC_ACLK, R9A07G043_CLK_P1, + 0x608, 0), +#endif }; static struct rzg2l_reset r9a07g043_resets[] = { @@ -318,6 +322,10 @@ DEF_RST(R9A07G043_ADC_PRESETN, 0x8a8, 0), DEF_RST(R9A07G043_ADC_ADRST_N, 0x8a8, 1), DEF_RST(R9A07G043_TSU_PRESETN, 0x8ac, 0), +#ifdef CONFIG_RISCV + DEF_RST(R9A07G043_NCEPLIC_ARESETN, 0x908, 0), +#endif + }; static const unsigned int r9a07g043_crit_mod_clks[] __initconst = { @@ -327,6 +335,7 @@ #endif #ifdef CONFIG_RISCV MOD_CLK_BASE + R9A07G043_IAX45_CLK, + MOD_CLK_BASE + R9A07G043_NCEPLIC_ACLK, #endif MOD_CLK_BASE + R9A07G043_DMAC_ACLK, }; --- linux-xilinx-6.8.0.orig/drivers/clk/renesas/r9a07g044-cpg.c +++ linux-xilinx-6.8.0/drivers/clk/renesas/r9a07g044-cpg.c @@ -178,7 +178,7 @@ DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4), DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi, mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), - DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi, + DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_shdi, mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier), DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4), DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4), --- linux-xilinx-6.8.0.orig/drivers/clk/samsung/clk-exynos-clkout.c +++ linux-xilinx-6.8.0/drivers/clk/samsung/clk-exynos-clkout.c @@ -13,9 +13,9 @@ #include #include #include +#include #include #include -#include #define EXYNOS_CLKOUT_NR_CLKS 1 #define EXYNOS_CLKOUT_PARENTS 32 @@ -84,17 +84,24 @@ static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask) { const struct exynos_clkout_variant *variant; + const struct of_device_id *match; if (!dev->parent) { dev_err(dev, "not instantiated from MFD\n"); return -EINVAL; } - variant = device_get_match_data(dev->parent); - if (!variant) { + /* + * 'exynos_clkout_ids' arrays is not the ids array matched by + * the dev->parent driver, so of_device_get_match_data() or + * device_get_match_data() cannot be used here. + */ + match = of_match_device(exynos_clkout_ids, dev->parent); + if (!match) { dev_err(dev, "cannot match parent device\n"); return -EINVAL; } + variant = match->data; *mux_mask = variant->mux_mask; --- linux-xilinx-6.8.0.orig/drivers/clk/samsung/clk-exynos850.c +++ linux-xilinx-6.8.0/drivers/clk/samsung/clk-exynos850.c @@ -605,7 +605,7 @@ static const struct samsung_gate_clock apm_gate_clks[] __initconst = { GATE(CLK_GOUT_CLKCMU_CMGP_BUS, "gout_clkcmu_cmgp_bus", "dout_apm_bus", - CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, 0, 0), + CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, CLK_SET_RATE_PARENT, 0), GATE(CLK_GOUT_CLKCMU_CHUB_BUS, "gout_clkcmu_chub_bus", "mout_clkcmu_chub_bus", CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 21, 0, 0), @@ -974,19 +974,19 @@ static const struct samsung_mux_clock cmgp_mux_clks[] __initconst = { MUX(CLK_MOUT_CMGP_ADC, "mout_cmgp_adc", mout_cmgp_adc_p, CLK_CON_MUX_CLK_CMGP_ADC, 0, 1), - MUX(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p, - CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1), - MUX(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p, - CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1), + MUX_F(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p, + CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1, CLK_SET_RATE_PARENT, 0), + MUX_F(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p, + CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1, CLK_SET_RATE_PARENT, 0), }; static const struct samsung_div_clock cmgp_div_clks[] __initconst = { DIV(CLK_DOUT_CMGP_ADC, "dout_cmgp_adc", "gout_clkcmu_cmgp_bus", CLK_CON_DIV_DIV_CLK_CMGP_ADC, 0, 4), - DIV(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0", - CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5), - DIV(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1", - CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5), + DIV_F(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0", + CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5, CLK_SET_RATE_PARENT, 0), + DIV_F(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1", + CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5, CLK_SET_RATE_PARENT, 0), }; static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = { @@ -1001,12 +1001,12 @@ "gout_clkcmu_cmgp_bus", CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK, 21, CLK_IGNORE_UNUSED, 0), GATE(CLK_GOUT_CMGP_USI0_IPCLK, "gout_cmgp_usi0_ipclk", "dout_cmgp_usi0", - CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, 0, 0), + CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, CLK_SET_RATE_PARENT, 0), GATE(CLK_GOUT_CMGP_USI0_PCLK, "gout_cmgp_usi0_pclk", "gout_clkcmu_cmgp_bus", CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK, 21, 0, 0), GATE(CLK_GOUT_CMGP_USI1_IPCLK, "gout_cmgp_usi1_ipclk", "dout_cmgp_usi1", - CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, 0, 0), + CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, CLK_SET_RATE_PARENT, 0), GATE(CLK_GOUT_CMGP_USI1_PCLK, "gout_cmgp_usi1_pclk", "gout_clkcmu_cmgp_bus", CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK, 21, 0, 0), @@ -1557,8 +1557,9 @@ mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1), MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user", mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1), - MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p, - PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1), + MUX_F(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", + mout_peri_spi_user_p, PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1, + CLK_SET_RATE_PARENT, 0), }; static const struct samsung_div_clock peri_div_clks[] __initconst = { @@ -1568,8 +1569,8 @@ CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5), DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2", CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5), - DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", - CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5), + DIV_F(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", + CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5, CLK_SET_RATE_PARENT, 0), }; static const struct samsung_gate_clock peri_gate_clks[] __initconst = { @@ -1611,7 +1612,7 @@ "mout_peri_bus_user", CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0), GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0", - CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0), + CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, CLK_SET_RATE_PARENT, 0), GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user", CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0), GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk", --- linux-xilinx-6.8.0.orig/drivers/clk/samsung/clk-exynosautov9.c +++ linux-xilinx-6.8.0/drivers/clk/samsung/clk-exynosautov9.c @@ -352,13 +352,13 @@ /* CMU_TOP_PURECLKCOMP */ PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk", PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL), - PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared1_pll", "oscclk", + PLL(pll_0822x, FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk", PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL), - PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared2_pll", "oscclk", + PLL(pll_0822x, FOUT_SHARED2_PLL, "fout_shared2_pll", "oscclk", PLL_LOCKTIME_PLL_SHARED2, PLL_CON3_PLL_SHARED2, NULL), - PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared3_pll", "oscclk", + PLL(pll_0822x, FOUT_SHARED3_PLL, "fout_shared3_pll", "oscclk", PLL_LOCKTIME_PLL_SHARED3, PLL_CON3_PLL_SHARED3, NULL), - PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared4_pll", "oscclk", + PLL(pll_0822x, FOUT_SHARED4_PLL, "fout_shared4_pll", "oscclk", PLL_LOCKTIME_PLL_SHARED4, PLL_CON3_PLL_SHARED4, NULL), }; --- linux-xilinx-6.8.0.orig/drivers/clk/si5324.h +++ linux-xilinx-6.8.0/drivers/clk/si5324.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Si5324 clock generator platform data + * + * Copyright (C) 2017-2018 Xilinx, Inc. + */ + +#ifndef __LINUX_PLATFORM_DATA_SI5324_H__ +#define __LINUX_PLATFORM_DATA_SI5324_H__ + +/** + * enum si5324_pll_src - Si5324 pll clock source + * + * @SI5324_PLL_SRC_DEFAULT: Default, do not change eeprom config + * @SI5324_PLL_SRC_XTAL: Pll source clock is XTAL input + * @SI5324_PLL_SRC_CLKIN1: Pll source clock is CLKIN1 input + * @SI5324_PLL_SRC_CLKIN2: Pll source clock is CLKIN2 input + * + * Defines enums for clock sources. + */ +enum si5324_pll_src { + SI5324_PLL_SRC_XTAL = 0, + SI5324_PLL_SRC_CLKIN1 = 1, + SI5324_PLL_SRC_CLKIN2 = 2, +}; + +/** + * enum si5324_drive_strength - Si5324 clock output drive strength + * + * @SI5324_DRIVE_DEFAULT: Default, do not change eeprom config + * @SI5324_DRIVE_2MA: 2mA clock output drive strength + * @SI5324_DRIVE_4MA: 4mA clock output drive strength + * @SI5324_DRIVE_6MA: 6mA clock output drive strength + * @SI5324_DRIVE_8MA: 8mA clock output drive strength + * + * Defines enums for drive strength + */ +enum si5324_drive_strength { + SI5324_DRIVE_DEFAULT = 0, + SI5324_DRIVE_2MA = 2, + SI5324_DRIVE_4MA = 4, + SI5324_DRIVE_6MA = 6, + SI5324_DRIVE_8MA = 8, +}; + +/** + * struct si5324_clkout_config - Si5324 clock output configuration + * + * @drive: output drive strength + * @rate: clkout rate + */ +struct si5324_clkout_config { + enum si5324_drive_strength drive; + unsigned long rate; +}; + +/** + * struct si5324_platform_data - Platform data for the Si5324 clock driver + * + * @pll_src: Pll source clock setting + * @clkout: Array of clkout configuration + */ +struct si5324_platform_data { + enum si5324_pll_src pll_src; + struct si5324_clkout_config clkout[2]; +}; + +#endif --- linux-xilinx-6.8.0.orig/drivers/clk/si5324drv.c +++ linux-xilinx-6.8.0/drivers/clk/si5324drv.c @@ -0,0 +1,383 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Si5324 clock driver + * + * Copyright (C) 2017-2018 Xilinx, Inc. + * + * Author: Venkateshwar Rao G + * Leon Woestenberg + */ + +#include +#include +#include "si5324drv.h" + +/** + * si5324_rate_approx - Find closest rational approximation N2_LS/N3 fraction. + * + * @f: Holds the N2_LS/N3 fraction in 36.28 fixed point notation. + * @md: Holds the maximum denominator (N3) value allowed. + * @num: Store the numinator (N2_LS) found. + * @denom: Store the denominator (N3) found. + * + * This function finds the closest rational approximation. + * It allows only n/1 solution and as a part of the calculation + * multiply fraction until no digits after the decimal point and + * continued fraction and check denominator at each step. + */ +void si5324_rate_approx(u64 f, u64 md, u32 *num, u32 *denom) +{ + u64 a, h[3] = { 0, 1, 0 }, k[3] = { 1, 0, 0 }; + u64 x, d, m, n = 1; + int i = 0; + + if (md <= 1) { + *denom = 1; + *num = (u32)(f >> 28); + return; + } + + n <<= 28; + for (i = 0; i < 28; i++) { + if ((f & 0x1) == 0) { + n >>= 1; + f >>= 1; + } else { + break; + } + } + d = f; + + for (i = 0; i < 64; i++) { + a = n ? (div64_u64(d, n)) : 0; + if (i && !a) + break; + x = d; + d = n; + div64_u64_rem(x, n, &m); + n = m; + x = a; + if (k[1] * a + k[0] >= md) { + x = div64_u64((md - k[0]), k[1]); + if (x * 2 >= a || k[1] >= md) + i = 65; + else + break; + } + h[2] = x * h[1] + h[0]; + h[0] = h[1]; + h[1] = h[2]; + k[2] = x * k[1] + k[0]; + k[0] = k[1]; + k[1] = k[2]; + } + + *denom = (u32)k[1]; + *num = (u32)h[1]; +} + +/** + * si5324_find_n2ls - Search through the possible settings for the N2_LS. + * + * @settings: Holds the settings up till now. + * + * This function finds the best setting for N2_LS and N3n with the values + * for N1_HS, NCn_LS, and N2_HS. + * + * Return: 1 when the best possible result has been found, 0 on failure. + */ +static int si5324_find_n2ls(struct si5324_settingst *settings) +{ + u32 result = 0; + u64 f3_actual; + u64 fosc_actual; + u64 fout_actual; + u64 delta_fout; + u64 n2_ls_div_n3, mult_res; + u32 mult; + + n2_ls_div_n3 = div64_u64(div64_u64(div64_u64(settings->fosc, + (settings->fin >> SI5324_FIN_FOUT_SHIFT)), + (u64)settings->n2_hs), (u64)2); + + si5324_rate_approx(n2_ls_div_n3, settings->n31_max, &settings->n2_ls, + &settings->n31); + settings->n2_ls *= 2; + + if (settings->n2_ls < settings->n2_ls_min) { + mult = div64_u64(settings->n2_ls_min, settings->n2_ls); + div64_u64_rem(settings->n2_ls_min, settings->n2_ls, &mult_res); + mult = mult_res ? mult + 1 : mult; + settings->n2_ls *= mult; + settings->n31 *= mult; + } + + if (settings->n31 < settings->n31_min) { + mult = div64_u64(settings->n31_min, settings->n31); + div64_u64_rem(settings->n31_min, settings->n31, &mult_res); + mult = mult_res ? mult + 1 : mult; + settings->n2_ls *= mult; + settings->n31 *= mult; + } + pr_debug("Trying N2_LS = %d N3 = %d.\n", settings->n2_ls, + settings->n31); + + if (settings->n2_ls < settings->n2_ls_min || + settings->n2_ls > settings->n2_ls_max) { + pr_info("N2_LS out of range.\n"); + } else if ((settings->n31 < settings->n31_min) || + (settings->n31 > settings->n31_max)) { + pr_info("N3 out of range.\n"); + } else { + f3_actual = div64_u64(settings->fin, settings->n31); + fosc_actual = f3_actual * settings->n2_hs * settings->n2_ls; + fout_actual = div64_u64(fosc_actual, + (settings->n1_hs * settings->nc1_ls)); + delta_fout = fout_actual - settings->fout; + + if ((f3_actual < ((u64)SI5324_F3_MIN) << + SI5324_FIN_FOUT_SHIFT) || + (f3_actual > ((u64)SI5324_F3_MAX) << + SI5324_FIN_FOUT_SHIFT)) { + pr_debug("F3 frequency out of range.\n"); + } else if ((fosc_actual < ((u64)SI5324_FOSC_MIN) << + SI5324_FIN_FOUT_SHIFT) || + (fosc_actual > ((u64)SI5324_FOSC_MAX) << + SI5324_FIN_FOUT_SHIFT)) { + pr_debug("Fosc frequency out of range.\n"); + } else if ((fout_actual < ((u64)SI5324_FOUT_MIN) << + SI5324_FIN_FOUT_SHIFT) || + (fout_actual > ((u64)SI5324_FOUT_MAX) << + SI5324_FIN_FOUT_SHIFT)) { + pr_debug("Fout frequency out of range.\n"); + } else { + u64 divident = fosc_actual >> SI5324_FIN_FOUT_SHIFT; + + pr_debug("Found solution: fout = %dHz delta = %dHz.\n", + (u32)(fout_actual >> SI5324_FIN_FOUT_SHIFT), + (u32)(delta_fout >> SI5324_FIN_FOUT_SHIFT)); + pr_debug("fosc = %dkHz f3 = %dHz.\n", + (u32)(do_div(divident, 1000)), + (u32)(f3_actual >> SI5324_FIN_FOUT_SHIFT)); + + if (((u64)abs(delta_fout)) < + settings->best_delta_fout) { + settings->best_n1_hs = settings->n1_hs; + settings->best_nc1_ls = settings->nc1_ls; + settings->best_n2_hs = settings->n2_hs; + settings->best_n2_ls = settings->n2_ls; + settings->best_n3 = settings->n31; + settings->best_fout = fout_actual; + settings->best_delta_fout = abs(delta_fout); + if (delta_fout == 0) + result = 1; + } + } + } + return result; +} + +/** + * si5324_find_n2 - Find a valid setting for N2_HS and N2_LS. + * + * @settings: Holds the settings up till now. + * + * This function finds a valid settings for N2_HS and N2_LS. Iterates over + * all possibilities of N2_HS and then performs a binary search over the + * N2_LS values. + * + * Return: 1 when the best possible result has been found. + */ +static int si5324_find_n2(struct si5324_settingst *settings) +{ + u32 result = 0; + + for (settings->n2_hs = SI5324_N2_HS_MAX; settings->n2_hs >= + SI5324_N2_HS_MIN; settings->n2_hs--) { + pr_debug("Trying N2_HS = %d.\n", settings->n2_hs); + settings->n2_ls_min = (u32)(div64_u64(settings->fosc, + ((u64)(SI5324_F3_MAX * settings->n2_hs) + << SI5324_FIN_FOUT_SHIFT))); + + if (settings->n2_ls_min < SI5324_N2_LS_MIN) + settings->n2_ls_min = SI5324_N2_LS_MIN; + + settings->n2_ls_max = (u32)(div64_u64(settings->fosc, + ((u64)(SI5324_F3_MIN * + settings->n2_hs) << + SI5324_FIN_FOUT_SHIFT))); + if (settings->n2_ls_max > SI5324_N2_LS_MAX) + settings->n2_ls_max = SI5324_N2_LS_MAX; + + result = si5324_find_n2ls(settings); + if (result) + break; + } + return result; +} + +/** + * si5324_calc_ncls_limits - Calculates the valid range for NCn_LS. + * + * @settings: Holds the input and output frequencies and the setting + * for N1_HS. + * + * This function calculates the valid range for NCn_LS with the value + * for the output frequency and N1_HS already set in settings. + * + * Return: -1 when there are no valid settings, 0 otherwise. + */ +int si5324_calc_ncls_limits(struct si5324_settingst *settings) +{ + settings->nc1_ls_min = div64_u64(settings->n1_hs_min, + settings->n1_hs); + + if (settings->nc1_ls_min < SI5324_NC_LS_MIN) + settings->nc1_ls_min = SI5324_NC_LS_MIN; + if (settings->nc1_ls_min > 1 && (settings->nc1_ls_min & 0x1) == 1) + settings->nc1_ls_min++; + settings->nc1_ls_max = div64_u64(settings->n1_hs_max, settings->n1_hs); + + if (settings->nc1_ls_max > SI5324_NC_LS_MAX) + settings->nc1_ls_max = SI5324_NC_LS_MAX; + + if ((settings->nc1_ls_max & 0x1) == 1) + settings->nc1_ls_max--; + if ((settings->nc1_ls_max * settings->n1_hs < settings->n1_hs_min) || + (settings->nc1_ls_min * settings->n1_hs > settings->n1_hs_max)) + return -1; + + return 0; +} + +/** + * si5324_find_ncls - Find a valid setting for NCn_LS + * + * @settings: Holds the input and output frequencies, the setting for + * N1_HS, and the limits for NCn_LS. + * + * This function find a valid setting for NCn_LS that can deliver the correct + * output frequency. Assumes that the valid range is relatively small + * so a full search can be done (should be true for video clock frequencies). + * + * Return: 1 when the best possible result has been found. + */ +static int si5324_find_ncls(struct si5324_settingst *settings) +{ + u64 fosc_1; + u32 result; + + fosc_1 = settings->fout * settings->n1_hs; + for (settings->nc1_ls = settings->nc1_ls_min; + settings->nc1_ls <= settings->nc1_ls_max;) { + settings->fosc = fosc_1 * settings->nc1_ls; + pr_debug("Trying NCn_LS = %d: fosc = %dkHz.\n", + settings->nc1_ls, + (u32)(div64_u64((settings->fosc >> + SI5324_FIN_FOUT_SHIFT), 1000))); + + result = si5324_find_n2(settings); + if (result) + break; + if (settings->nc1_ls == 1) + settings->nc1_ls++; + else + settings->nc1_ls += 2; + } + return result; +} + +/** + * si5324_calcfreqsettings - Calculate the frequency settings + * + * @clkinfreq: Frequency of the input clock. + * @clkoutfreq: Desired output clock frequency. + * @clkactual: Actual clock frequency. + * @n1_hs: Set to the value for the N1_HS register. + * @ncn_ls: Set to the value for the NCn_LS register. + * @n2_hs: Set to the value for the N2_HS register. + * @n2_ls: Set to the value for the N2_LS register. + * @n3n: Set to the value for the N3n register. + * @bwsel: Set to the value for the BW_SEL register. + * + * This funciton calculates the frequency settings for the desired output + * frequency. + * + * Return: SI5324_SUCCESS for success, SI5324_ERR_FREQ when the + * requested frequency cannot be generated. + */ +int si5324_calcfreqsettings(u32 clkinfreq, u32 clkoutfreq, u32 *clkactual, + u8 *n1_hs, u32 *ncn_ls, u8 *n2_hs, u32 *n2_ls, + u32 *n3n, u8 *bwsel) +{ + struct si5324_settingst settings; + int result; + + settings.fin = (u64)clkinfreq << SI5324_FIN_FOUT_SHIFT; + settings.fout = (u64)clkoutfreq << SI5324_FIN_FOUT_SHIFT; + settings.best_delta_fout = settings.fout; + + settings.n1_hs_min = (int)(div64_u64(SI5324_FOSC_MIN, clkoutfreq)); + if (settings.n1_hs_min < SI5324_N1_HS_MIN * SI5324_NC_LS_MIN) + settings.n1_hs_min = SI5324_N1_HS_MIN * SI5324_NC_LS_MIN; + + settings.n1_hs_max = (int)(div64_u64(SI5324_FOSC_MAX, clkoutfreq)); + if (settings.n1_hs_max > SI5324_N1_HS_MAX * SI5324_NC_LS_MAX) + settings.n1_hs_max = SI5324_N1_HS_MAX * SI5324_NC_LS_MAX; + + settings.n31_min = div64_u64(clkinfreq, SI5324_F3_MAX); + if (settings.n31_min < SI5324_N3_MIN) + settings.n31_min = SI5324_N3_MIN; + + settings.n31_max = div64_u64(clkinfreq, SI5324_F3_MIN); + if (settings.n31_max > SI5324_N3_MAX) + settings.n31_max = SI5324_N3_MAX; + + /* Find a valid oscillator frequency with the highest setting of N1_HS + * possible (reduces power) + */ + for (settings.n1_hs = SI5324_N1_HS_MAX; + settings.n1_hs >= SI5324_N1_HS_MIN; settings.n1_hs--) { + pr_debug("Trying N1_HS = %d.\n", settings.n1_hs); + + result = si5324_calc_ncls_limits(&settings); + if (result) { + pr_debug("No valid settings\n"); + continue; + } + result = si5324_find_ncls(&settings); + if (result) + break; + } + + pr_debug("Si5324: settings.best_delta_fout = %llu\n", + (unsigned long long)settings.best_delta_fout); + pr_debug("Si5324: settings.fout = %llu\n", + (unsigned long long)settings.fout); + + if (settings.best_delta_fout == settings.fout) { + pr_debug("Si5324: No valid settings found."); + return SI5324_ERR_FREQ; + } + pr_debug("Si5324: Found solution: fout = %dHz.\n", + (u32)(settings.best_fout >> 28)); + + /* Post processing: convert temporary values to actual registers */ + *n1_hs = (u8)settings.best_n1_hs - 4; + *ncn_ls = settings.best_nc1_ls - 1; + *n2_hs = (u8)settings.best_n2_hs - 4; + *n2_ls = settings.best_n2_ls - 1; + *n3n = settings.best_n3 - 1; + /* + * How must the bandwidth selection be determined? + * Not all settings will be valid. + * refclk 2, 0xA2, BWSEL_REG=1010 (?) + * free running 2, 0x42, BWSEL_REG=0100 (?) + */ + *bwsel = 6; + + if (clkactual) + *clkactual = (settings.best_fout >> SI5324_FIN_FOUT_SHIFT); + + return SI5324_SUCCESS; +} --- linux-xilinx-6.8.0.orig/drivers/clk/si5324drv.h +++ linux-xilinx-6.8.0/drivers/clk/si5324drv.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Si5324 clock driver + * + * Copyright (C) 2017-2018 Xilinx, Inc. + */ + +#ifndef SI5324DRV_H_ +#define SI5324DRV_H_ + +#include + +/****************************************************************************** + * User settable defines that depend on the specific board design. + * The defaults are for the Xilinx KC705 board. + *****************************************************************************/ + +#define SI5324_XTAL_FREQ 114285000UL + +/****************************************************************************** + * Defines independent on the specific board design. Should not be changed. + *****************************************************************************/ + +#define SI5324_SUCCESS 0 /*< Operation was successful */ +#define SI5324_ERR_IIC -1 /*< IIC error occurred */ +#define SI5324_ERR_FREQ -2 /*< Could not calculate frequency setting */ +#define SI5324_ERR_PARM -3 /*< Invalid parameter */ + +#define SI5324_CLKSRC_CLK1 1 /*< Use clock input 1 */ +#define SI5324_CLKSRC_CLK2 2 /*< Use clock input 2 */ +#define SI5324_CLKSRC_XTAL 3 /*< Use crystal (free running mode) */ + +#define SI5324_FOSC_MIN 4850000000UL /*< Min oscillator frequency */ +#define SI5324_FOSC_MAX 5670000000UL /*< Max oscillator frequency */ +#define SI5324_F3_MIN 10000 /*< Min phase detector frequency */ +#define SI5324_F3_MAX 2000000 /*< Max phase detector frequency */ +#define SI5324_FIN_MIN 2000 /*< Min input frequency */ +#define SI5324_FIN_MAX 710000000UL /*< Max input frequency */ +#define SI5324_FOUT_MIN 2000 /*< Min output frequency */ +#define SI5324_FOUT_MAX 945000000UL /*< Max output frequency */ + +#define SI5324_N1_HS_MIN 6 +#define SI5324_N1_HS_MAX 11 +#define SI5324_NC_LS_MIN 1 +#define SI5324_NC_LS_MAX 0x100000 +#define SI5324_N2_HS_MIN 4 +#define SI5324_N2_HS_MAX 11 +#define SI5324_N2_LS_MIN 2 /* even values only */ +#define SI5324_N2_LS_MAX 0x100000 +#define SI5324_N3_MIN 1 +#define SI5324_N3_MAX 0x080000 +#define SI5324_FIN_FOUT_SHIFT 28 + +struct si5324_settingst { + /* high-speed output divider */ + u32 n1_hs_min; + u32 n1_hs_max; + u32 n1_hs; + + /* low-speed output divider for clkout1 */ + u32 nc1_ls_min; + u32 nc1_ls_max; + u32 nc1_ls; + + /* low-speed output divider for clkout2 */ + u32 nc2_ls_min; + u32 nc2_ls_max; + u32 nc2_ls; + + /* high-speed feedback divider (PLL multiplier) */ + u32 n2_hs; + /* low-speed feedback divider (PLL multiplier) */ + u32 n2_ls_min; + u32 n2_ls_max; + u32 n2_ls; + + /* input divider for clk1 */ + u32 n31_min; + u32 n31_max; + u32 n31; + + u64 fin; + u64 fout; + u64 fosc; + u64 best_delta_fout; + u64 best_fout; + u32 best_n1_hs; + u32 best_nc1_ls; + u32 best_n2_hs; + u32 best_n2_ls; + u32 best_n3; +}; + +int si5324_calcfreqsettings(u32 clkinfreq, u32 clkoutfreq, u32 *clkactual, + u8 *n1_hs, u32 *ncn_ls, u8 *n2_hs, + u32 *n2_ls, u32 *n3n, u8 *bwsel); +void si5324_rate_approx(u64 f, u64 md, u32 *num, u32 *denom); +int si5324_calc_ncls_limits(struct si5324_settingst *settings); + +#endif /* SI5324DRV_H_ */ --- linux-xilinx-6.8.0.orig/drivers/clk/sifive/sifive-prci.c +++ linux-xilinx-6.8.0/drivers/clk/sifive/sifive-prci.c @@ -4,7 +4,6 @@ * Copyright (C) 2020 Zong Li */ -#include #include #include #include @@ -536,13 +535,6 @@ init.name, r); return r; } - - r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); - if (r) { - dev_warn(dev, "Failed to register clkdev for %s: %d\n", - init.name, r); - return r; - } pd->hw_clks.hws[i] = &pic->hw; } --- linux-xilinx-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ linux-xilinx-6.8.0/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -182,6 +182,8 @@ &ccu_nkm_ops, CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT), .features = CCU_FEATURE_CLOSEST_RATE, + .min_rate = 500000000, + .max_rate = 1400000000, }, }; --- linux-xilinx-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ linux-xilinx-6.8.0/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -1181,11 +1181,18 @@ SUN50I_H6_USB3_CLK_REG, }; +static struct ccu_mux_nb sun50i_h6_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, + .bypass_index = 0, /* index of 24 MHz oscillator */ +}; + static int sun50i_h6_ccu_probe(struct platform_device *pdev) { void __iomem *reg; + int i, ret; u32 val; - int i; reg = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(reg)) @@ -1252,7 +1259,15 @@ val |= BIT(24); writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG); - return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); + if (ret) + return ret; + + /* Reparent CPU during PLL CPUX rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_h6_cpu_nb); + + return 0; } static const struct of_device_id sun50i_h6_ccu_ids[] = { --- linux-xilinx-6.8.0.orig/drivers/clk/sunxi-ng/ccu_common.c +++ linux-xilinx-6.8.0/drivers/clk/sunxi-ng/ccu_common.c @@ -44,6 +44,16 @@ unsigned long current_rate, unsigned long best_rate) { + unsigned long min_rate, max_rate; + + clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate); + + if (current_rate > max_rate) + return false; + + if (current_rate < min_rate) + return false; + if (common->features & CCU_FEATURE_CLOSEST_RATE) return abs(current_rate - target_rate) < abs(best_rate - target_rate); @@ -138,6 +148,21 @@ } } + for (i = 0; i < desc->num_ccu_clks; i++) { + struct ccu_common *cclk = desc->ccu_clks[i]; + + if (!cclk) + continue; + + if (cclk->max_rate) + clk_hw_set_rate_range(&cclk->hw, cclk->min_rate, + cclk->max_rate); + else + WARN(cclk->min_rate, + "No max_rate, ignoring min_rate of clock %d - %s\n", + i, clk_hw_get_name(&cclk->hw)); + } + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, desc->hw_clks); if (ret) --- linux-xilinx-6.8.0.orig/drivers/clk/sunxi-ng/ccu_common.h +++ linux-xilinx-6.8.0/drivers/clk/sunxi-ng/ccu_common.h @@ -31,6 +31,9 @@ u16 lock_reg; u32 prediv; + unsigned long min_rate; + unsigned long max_rate; + unsigned long features; spinlock_t *lock; struct clk_hw hw; --- linux-xilinx-6.8.0.orig/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ linux-xilinx-6.8.0/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -51,6 +51,8 @@ #define WZRD_CLKFBOUT_MULT_SHIFT 8 #define WZRD_CLKFBOUT_MULT_MASK (0xff << WZRD_CLKFBOUT_MULT_SHIFT) +#define WZRD_CLKFBOUT_MULT_FRAC_MASK GENMASK(25, 16) +#define WZRD_CLKFBOUT_O_MASK GENMASK(7, 0) #define WZRD_CLKFBOUT_L_SHIFT 0 #define WZRD_CLKFBOUT_H_SHIFT 8 #define WZRD_CLKFBOUT_L_MASK GENMASK(7, 0) @@ -86,14 +88,14 @@ #define DIV_O 0x01 #define DIV_ALL 0x03 -#define WZRD_M_MIN 2 -#define WZRD_M_MAX 128 -#define WZRD_D_MIN 1 -#define WZRD_D_MAX 106 -#define WZRD_VCO_MIN 800000000 -#define WZRD_VCO_MAX 1600000000 -#define WZRD_O_MIN 1 -#define WZRD_O_MAX 128 +#define WZRD_M_MIN 2ULL +#define WZRD_M_MAX 128ULL +#define WZRD_D_MIN 1ULL +#define WZRD_D_MAX 106ULL +#define WZRD_VCO_MIN 800000000ULL +#define WZRD_VCO_MAX 1600000000ULL +#define WZRD_O_MIN 2ULL +#define WZRD_O_MAX 128ULL #define VER_WZRD_M_MIN 4 #define VER_WZRD_M_MAX 432 #define VER_WZRD_D_MIN 1 @@ -154,8 +156,10 @@ * @flags: clk_wzrd divider flags * @table: array of value/divider pairs, last entry should have div = 0 * @m: value of the multiplier + * @m_frac: fractional value of the multiplier * @d: value of the common divider * @o: value of the leaf divider + * @o_frac: value of the fractional leaf divider * @lock: register lock */ struct clk_wzrd_divider { @@ -167,8 +171,10 @@ u8 flags; const struct clk_div_table *table; u32 m; + u32 m_frac; u32 d; u32 o; + u32 o_frac; spinlock_t *lock; /* divider lock */ }; @@ -373,38 +379,40 @@ unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - u64 vco_freq, freq, diff, vcomin, vcomax; - u32 m, d, o; - u32 mmin, mmax, dmin, dmax, omin, omax; + u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL; + u64 m, d, o; + u64 mmin, mmax, dmin, dmax, omin, omax, mdmin, mdmax; - mmin = WZRD_M_MIN; - mmax = WZRD_M_MAX; + mmin = WZRD_M_MIN << 3; + mmax = WZRD_M_MAX << 3; dmin = WZRD_D_MIN; dmax = WZRD_D_MAX; - omin = WZRD_O_MIN; - omax = WZRD_O_MAX; - vcomin = WZRD_VCO_MIN; - vcomax = WZRD_VCO_MAX; + omin = WZRD_O_MIN << 3; + omax = WZRD_O_MAX << 3; + vcomin = WZRD_VCO_MIN << 3; + vcomax = WZRD_VCO_MAX << 3; for (m = mmin; m <= mmax; m++) { - for (d = dmin; d <= dmax; d++) { - vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d); - if (vco_freq >= vcomin && vco_freq <= vcomax) { - for (o = omin; o <= omax; o++) { - freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); - diff = abs(freq - rate); - - if (diff < WZRD_MIN_ERR) { - divider->m = m; - divider->d = d; - divider->o = o; - return 0; - } - } + mdmin = max(dmin, div64_u64(parent_rate * m + vcomax / 2, vcomax)); + mdmax = min(dmax, div64_u64(parent_rate * m + vcomin / 2, vcomin)); + for (d = mdmin; d <= mdmax; d++) { + vco_freq = DIV_ROUND_CLOSEST_ULL((parent_rate * m), d); + o = DIV_ROUND_CLOSEST_ULL(vco_freq, rate); + if (o < omin || o > omax) + continue; + freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o); + diff = freq - rate; + if (diff < best_diff) { + best_diff = diff; + divider->m = m >> 3; + divider->m_frac = (m - (divider->m << 3)) * 125; + divider->d = d; + divider->o = o >> 3; + divider->o_frac = (o - (divider->o << 3)) * 125; } } } - return -EBUSY; + return best_diff < WZRD_MIN_ERR ? 0 : -EBUSY; } static int clk_wzrd_reconfig(struct clk_wzrd_divider *divider, void __iomem *div_addr) @@ -497,33 +505,22 @@ unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - unsigned long vco_freq, rate_div, clockout0_div; void __iomem *div_addr = divider->base; - u32 reg, pre, f; + u32 reg; int err; err = clk_wzrd_get_divisors(hw, rate, parent_rate); if (err) return err; - vco_freq = DIV_ROUND_CLOSEST(parent_rate * divider->m, divider->d); - rate_div = DIV_ROUND_CLOSEST_ULL((vco_freq * WZRD_FRAC_POINTS), rate); - - clockout0_div = div_u64(rate_div, WZRD_FRAC_POINTS); - - pre = DIV_ROUND_CLOSEST_ULL(vco_freq * WZRD_FRAC_POINTS, rate); - f = (pre - (clockout0_div * WZRD_FRAC_POINTS)); - f &= WZRD_CLKOUT_FRAC_MASK; - - reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) | - FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f); + reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, divider->o) | + FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, divider->o_frac); writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 2)); - /* Set divisor and clear phase offset */ reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->m) | + FIELD_PREP(WZRD_CLKFBOUT_MULT_FRAC_MASK, divider->m_frac) | FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->d); writel(reg, divider->base + WZRD_CLK_CFG_REG(0, 0)); - writel(divider->o, divider->base + WZRD_CLK_CFG_REG(0, 2)); writel(0, divider->base + WZRD_CLK_CFG_REG(0, 3)); div_addr = divider->base + WZRD_DR_INIT_REG_OFFSET; return clk_wzrd_reconfig(divider, div_addr); @@ -565,18 +562,19 @@ unsigned long parent_rate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); - u32 m, d, o, div, reg, f; + u32 m, d, o, reg, f, mf; + u64 mul; reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 0)); d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg); m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg); + mf = FIELD_GET(WZRD_CLKFBOUT_MULT_FRAC_MASK, reg); reg = readl(divider->base + WZRD_CLK_CFG_REG(0, 2)); o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg); f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg); - div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS); - return divider_recalc_rate(hw, parent_rate * m, div, divider->table, - divider->flags, divider->width); + mul = m * 1000 + mf; + return DIV_ROUND_CLOSEST_ULL(parent_rate * mul, d * (o * 1000 + f)); } static unsigned long clk_wzrd_recalc_rate_all_ver(struct clk_hw *hw, @@ -649,6 +647,25 @@ unsigned long *prate) { struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); + u32 m, d, o; + int err; + + err = clk_wzrd_get_divisors(hw, rate, *prate); + if (err) + return err; + + m = divider->m; + d = divider->d; + o = divider->o; + + rate = div_u64(*prate * (m * 1000 + divider->m_frac), d * (o * 1000 + divider->o_frac)); + return rate; +} + +static long clk_wzrd_ver_round_rate_all(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw); unsigned long int_freq; u32 m, d, o, div, f; int err; @@ -679,7 +696,7 @@ }; static const struct clk_ops clk_wzrd_ver_div_all_ops = { - .round_rate = clk_wzrd_round_rate_all, + .round_rate = clk_wzrd_ver_round_rate_all, .set_rate = clk_wzrd_dynamic_all_ver, .recalc_rate = clk_wzrd_recalc_rate_all_ver, }; --- linux-xilinx-6.8.0.orig/drivers/clk/xilinx/xlnx_vcu.c +++ linux-xilinx-6.8.0/drivers/clk/xilinx/xlnx_vcu.c @@ -11,11 +11,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -46,28 +48,6 @@ #define FVCO_MIN (1500U * MHZ) #define FVCO_MAX (3000U * MHZ) -/** - * struct xvcu_device - Xilinx VCU init device structure - * @dev: Platform device - * @pll_ref: pll ref clock source - * @aclk: axi clock source - * @logicore_reg_ba: logicore reg base address - * @vcu_slcr_ba: vcu_slcr Register base address - * @pll: handle for the VCU PLL - * @pll_post: handle for the VCU PLL post divider - * @clk_data: clocks provided by the vcu clock provider - */ -struct xvcu_device { - struct device *dev; - struct clk *pll_ref; - struct clk *aclk; - struct regmap *logicore_reg_ba; - void __iomem *vcu_slcr_ba; - struct clk_hw *pll; - struct clk_hw *pll_post; - struct clk_hw_onecell_data *clk_data; -}; - static struct regmap_config vcu_settings_regmap_config = { .name = "regmap", .reg_bits = 32, @@ -223,6 +203,78 @@ iowrite32(value, iomem + offset); } +/** + * xvcu_get_color_depth - read the color depth register + * @xvcu: Pointer to the xvcu_device structure + * + * Return: Returns 32bit value + * + */ +u32 xvcu_get_color_depth(struct xvcu_device *xvcu) +{ + u32 value; + + if (!regmap_read(xvcu->logicore_reg_ba, VCU_ENC_COLOR_DEPTH, &value)) + return value; + else + return 0; +} +EXPORT_SYMBOL_GPL(xvcu_get_color_depth); + +/** + * xvcu_get_memory_depth - read the memory depth register + * @xvcu: Pointer to the xvcu_device structure + * + * Return: Returns 32bit value + * + */ +u32 xvcu_get_memory_depth(struct xvcu_device *xvcu) +{ + u32 value; + + if (!regmap_read(xvcu->logicore_reg_ba, VCU_MEMORY_DEPTH, &value)) + return value; + else + return 0; +} +EXPORT_SYMBOL_GPL(xvcu_get_memory_depth); + +/** + * xvcu_get_clock_frequency - provide the core clock frequency + * @xvcu: Pointer to the xvcu_device structure + * + * Return: Returns 32bit value + * + */ +u32 xvcu_get_clock_frequency(struct xvcu_device *xvcu) +{ + u32 value; + + if (!regmap_read(xvcu->logicore_reg_ba, VCU_CORE_CLK, &value)) + return value * MHZ; + else + return 0; +} +EXPORT_SYMBOL_GPL(xvcu_get_clock_frequency); + +/** + * xvcu_get_num_cores - read the number of core register + * @xvcu: Pointer to the xvcu_device structure + * + * Return: Returns 32bit value + * + */ +u32 xvcu_get_num_cores(struct xvcu_device *xvcu) +{ + u32 value; + + if (!regmap_read(xvcu->logicore_reg_ba, VCU_NUM_CORE, &value)) + return value; + else + return 0; +} +EXPORT_SYMBOL_GPL(xvcu_get_num_cores); + #define to_vcu_pll(_hw) container_of(_hw, struct vcu_pll, hw) struct vcu_pll { @@ -547,7 +599,7 @@ return PTR_ERR(hw); xvcu->pll_post = hw; - parent_data[0].fw_name = "pll_ref"; + parent_data[0].fw_name = "dummy_name"; parent_data[1].hw = xvcu->pll_post; hws[CLK_XVCU_ENC_CORE] = @@ -587,8 +639,8 @@ xvcu_clk_hw_unregister_leaf(hws[CLK_XVCU_ENC_MCU]); if (!IS_ERR_OR_NULL(hws[CLK_XVCU_ENC_CORE])) xvcu_clk_hw_unregister_leaf(hws[CLK_XVCU_ENC_CORE]); - - clk_hw_unregister_fixed_factor(xvcu->pll_post); + if (!IS_ERR_OR_NULL(xvcu->pll_post)) + clk_hw_unregister_fixed_factor(xvcu->pll_post); } /** @@ -676,6 +728,24 @@ * Bit 0 : Gasket isolation * Bit 1 : put VCU out of reset */ + xvcu->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(xvcu->reset_gpio)) { + ret = PTR_ERR(xvcu->reset_gpio); + dev_err(&pdev->dev, "failed to get reset gpio for vcu.\n"); + goto error_get_gpio; + } + + if (xvcu->reset_gpio) { + gpiod_set_value(xvcu->reset_gpio, 0); + /* min 2 clock cycle of vcu pll_ref, slowest freq is 33.33KHz */ + usleep_range(60, 120); + gpiod_set_value(xvcu->reset_gpio, 1); + usleep_range(60, 120); + } else { + dev_warn(&pdev->dev, "No reset gpio info from dts for vcu. This may lead to incorrect functionality if VCU isolation is removed post initialization.\n"); + } + regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE); ret = xvcu_register_clock_provider(xvcu); @@ -686,10 +756,17 @@ dev_set_drvdata(&pdev->dev, xvcu); + ret = devm_of_platform_populate(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Failed to register allegro codecs\n"); + goto error_clk_provider; + } + return 0; error_clk_provider: xvcu_unregister_clock_provider(xvcu); +error_get_gpio: clk_disable_unprepare(xvcu->aclk); return ret; } @@ -711,6 +788,13 @@ xvcu_unregister_clock_provider(xvcu); /* Add the Gasket isolation and put the VCU in reset. */ + if (xvcu->reset_gpio) { + gpiod_set_value(xvcu->reset_gpio, 0); + /* min 2 clock cycle of vcu pll_ref, slowest freq is 33.33KHz */ + usleep_range(60, 120); + gpiod_set_value(xvcu->reset_gpio, 1); + usleep_range(60, 120); + } regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0); clk_disable_unprepare(xvcu->aclk); --- linux-xilinx-6.8.0.orig/drivers/clk/zynq/clkc.c +++ linux-xilinx-6.8.0/drivers/clk/zynq/clkc.c @@ -42,6 +42,7 @@ #define SLCR_SWDT_CLK_SEL (zynq_clkc_base + 0x204) #define NUM_MIO_PINS 54 +#define CLK_NAME_LEN 16 #define DBG_CLK_CTRL_CLKACT_TRC BIT(0) #define DBG_CLK_CTRL_CPU_1XCLKACT BIT(1) @@ -215,7 +216,7 @@ int i; u32 tmp; int ret; - char *clk_name; + char clk_name[CLK_NAME_LEN]; unsigned int fclk_enable = 0; const char *clk_output_name[clk_max]; const char *cpu_parents[4]; @@ -426,12 +427,10 @@ "gem1_emio_mux", CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); - tmp = strlen("mio_clk_00x"); - clk_name = kmalloc(tmp, GFP_KERNEL); for (i = 0; i < NUM_MIO_PINS; i++) { int idx; - snprintf(clk_name, tmp, "mio_clk_%2.2d", i); + snprintf(clk_name, CLK_NAME_LEN, "mio_clk_%2.2d", i); idx = of_property_match_string(np, "clock-names", clk_name); if (idx >= 0) can_mio_mux_parents[i] = of_clk_get_parent_name(np, @@ -439,7 +438,6 @@ else can_mio_mux_parents[i] = dummy_nm; } - kfree(clk_name); clk_register_mux(NULL, "can_mux", periph_parents, 4, CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock); --- linux-xilinx-6.8.0.orig/drivers/clk/zynqmp/divider.c +++ linux-xilinx-6.8.0/drivers/clk/zynqmp/divider.c @@ -2,7 +2,8 @@ /* * Zynq UltraScale+ MPSoC Divider support * - * Copyright (C) 2016-2019 Xilinx + * Copyright (C), 2016 - 2019 Xilinx + * Copyright (C), 2023 - 2024 Advanced Micro Devices, Inc. * * Adjustable divider clock implementation */ --- linux-xilinx-6.8.0.orig/drivers/clocksource/arm_global_timer.c +++ linux-xilinx-6.8.0/drivers/clocksource/arm_global_timer.c @@ -32,7 +32,7 @@ #define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */ #define GT_CONTROL_AUTO_INC BIT(3) /* banked */ #define GT_CONTROL_PRESCALER_SHIFT 8 -#define GT_CONTROL_PRESCALER_MAX 0xF +#define GT_CONTROL_PRESCALER_MAX 0xFF #define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \ GT_CONTROL_PRESCALER_SHIFT) --- linux-xilinx-6.8.0.orig/drivers/clocksource/timer-cadence-ttc.c +++ linux-xilinx-6.8.0/drivers/clocksource/timer-cadence-ttc.c @@ -487,6 +487,13 @@ u32 timer_width = 16; struct device_node *timer = pdev->dev.of_node; + /* + * If pwm-cells property is present in TTC node, + * it would be treated as PWM device. + */ + if (of_property_read_bool(timer, "#pwm-cells")) + return -ENODEV; + if (initialized) return 0; --- linux-xilinx-6.8.0.orig/drivers/clocksource/timer-riscv.c +++ linux-xilinx-6.8.0/drivers/clocksource/timer-riscv.c @@ -108,6 +108,9 @@ { struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu); + /* Clear timer interrupt */ + riscv_clock_event_stop(); + ce->cpumask = cpumask_of(cpu); ce->irq = riscv_clock_event_irq; if (riscv_timer_cannot_wake_cpu) --- linux-xilinx-6.8.0.orig/drivers/comedi/drivers/vmk80xx.c +++ linux-xilinx-6.8.0/drivers/comedi/drivers/vmk80xx.c @@ -641,33 +641,22 @@ struct vmk80xx_private *devpriv = dev->private; struct usb_interface *intf = comedi_to_usb_interface(dev); struct usb_host_interface *iface_desc = intf->cur_altsetting; - struct usb_endpoint_descriptor *ep_desc; - int i; + struct usb_endpoint_descriptor *ep_rx_desc, *ep_tx_desc; + int ret; - if (iface_desc->desc.bNumEndpoints != 2) - return -ENODEV; - - for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { - ep_desc = &iface_desc->endpoint[i].desc; - - if (usb_endpoint_is_int_in(ep_desc) || - usb_endpoint_is_bulk_in(ep_desc)) { - if (!devpriv->ep_rx) - devpriv->ep_rx = ep_desc; - continue; - } + if (devpriv->model == VMK8061_MODEL) + ret = usb_find_common_endpoints(iface_desc, &ep_rx_desc, + &ep_tx_desc, NULL, NULL); + else + ret = usb_find_common_endpoints(iface_desc, NULL, NULL, + &ep_rx_desc, &ep_tx_desc); - if (usb_endpoint_is_int_out(ep_desc) || - usb_endpoint_is_bulk_out(ep_desc)) { - if (!devpriv->ep_tx) - devpriv->ep_tx = ep_desc; - continue; - } - } - - if (!devpriv->ep_rx || !devpriv->ep_tx) + if (ret) return -ENODEV; + devpriv->ep_rx = ep_rx_desc; + devpriv->ep_tx = ep_tx_desc; + if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx)) return -EINVAL; --- linux-xilinx-6.8.0.orig/drivers/counter/ti-eqep.c +++ linux-xilinx-6.8.0/drivers/counter/ti-eqep.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -376,6 +377,7 @@ struct counter_device *counter; struct ti_eqep_cnt *priv; void __iomem *base; + struct clk *clk; int err; counter = devm_counter_alloc(dev, sizeof(*priv)); @@ -415,6 +417,10 @@ pm_runtime_enable(dev); pm_runtime_get_sync(dev); + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "failed to enable clock\n"); + err = counter_add(counter); if (err < 0) { pm_runtime_put_sync(dev); --- linux-xilinx-6.8.0.orig/drivers/cpufreq/Kconfig.arm +++ linux-xilinx-6.8.0/drivers/cpufreq/Kconfig.arm @@ -173,6 +173,7 @@ config ARM_QCOM_CPUFREQ_HW tristate "QCOM CPUFreq HW driver" depends on ARCH_QCOM || COMPILE_TEST + depends on COMMON_CLK help Support for the CPUFreq HW driver. Some QCOM chipsets have a HW engine to offload the steps --- linux-xilinx-6.8.0.orig/drivers/cpufreq/acpi-cpufreq.c +++ linux-xilinx-6.8.0/drivers/cpufreq/acpi-cpufreq.c @@ -890,8 +890,10 @@ if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency) pr_warn(FW_WARN "P-state 0 is not max freq\n"); - if (acpi_cpufreq_driver.set_boost) + if (acpi_cpufreq_driver.set_boost) { set_boost(policy, acpi_cpufreq_driver.boost_enabled); + policy->boost_enabled = acpi_cpufreq_driver.boost_enabled; + } return result; --- linux-xilinx-6.8.0.orig/drivers/cpufreq/amd-pstate-ut.c +++ linux-xilinx-6.8.0/drivers/cpufreq/amd-pstate-ut.c @@ -26,10 +26,11 @@ #include #include #include -#include #include +#include "amd-pstate.h" + /* * Abbreviations: * amd_pstate_ut: used as a shortform for AMD P-State unit test. --- linux-xilinx-6.8.0.orig/drivers/cpufreq/amd-pstate.c +++ linux-xilinx-6.8.0/drivers/cpufreq/amd-pstate.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -45,11 +44,44 @@ #include #include #include + +#include "amd-pstate.h" #include "amd-pstate-trace.h" #define AMD_PSTATE_TRANSITION_LATENCY 20000 #define AMD_PSTATE_TRANSITION_DELAY 1000 +#define AMD_CPPC_EPP_PERFORMANCE 0x00 +#define AMD_CPPC_EPP_BALANCE_PERFORMANCE 0x80 +#define AMD_CPPC_EPP_BALANCE_POWERSAVE 0xBF +#define AMD_CPPC_EPP_POWERSAVE 0xFF + +/* + * enum amd_pstate_mode - driver working mode of amd pstate + */ +enum amd_pstate_mode { + AMD_PSTATE_UNDEFINED = 0, + AMD_PSTATE_DISABLE, + AMD_PSTATE_PASSIVE, + AMD_PSTATE_ACTIVE, + AMD_PSTATE_GUIDED, + AMD_PSTATE_MAX, +}; + +static const char * const amd_pstate_mode_string[] = { + [AMD_PSTATE_UNDEFINED] = "undefined", + [AMD_PSTATE_DISABLE] = "disable", + [AMD_PSTATE_PASSIVE] = "passive", + [AMD_PSTATE_ACTIVE] = "active", + [AMD_PSTATE_GUIDED] = "guided", + NULL, +}; + +struct quirk_entry { + u32 nominal_freq; + u32 lowest_freq; +}; + /* * TODO: We need more time to fine tune processors with shared memory solution * with community together. @@ -64,6 +96,7 @@ static struct cpufreq_driver amd_pstate_epp_driver; static int cppc_state = AMD_PSTATE_UNDEFINED; static bool cppc_enabled; +static struct quirk_entry *quirks; /* * AMD Energy Preference Performance (EPP) @@ -108,6 +141,41 @@ typedef int (*cppc_mode_transition_fn)(int); +static struct quirk_entry quirk_amd_7k62 = { + .nominal_freq = 2600, + .lowest_freq = 550, +}; + +static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi) +{ + /** + * match the broken bios for family 17h processor support CPPC V2 + * broken BIOS lack of nominal_freq and lowest_freq capabilities + * definition in ACPI tables + */ + if (boot_cpu_has(X86_FEATURE_ZEN2)) { + quirks = dmi->driver_data; + pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident); + return 1; + } + + return 0; +} + +static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = { + { + .callback = dmi_matched_7k62_bios_bug, + .ident = "AMD EPYC 7K62", + .matches = { + DMI_MATCH(DMI_BIOS_VERSION, "5.14"), + DMI_MATCH(DMI_BIOS_RELEASE, "12/12/2019"), + }, + .driver_data = &quirk_amd_7k62, + }, + {} +}; +MODULE_DEVICE_TABLE(dmi, amd_pstate_quirks_table); + static inline int get_mode_idx_from_str(const char *str, size_t size) { int i; @@ -570,7 +638,7 @@ if (target_perf < capacity) des_perf = DIV_ROUND_UP(cap_perf * target_perf, capacity); - min_perf = READ_ONCE(cpudata->highest_perf); + min_perf = READ_ONCE(cpudata->lowest_perf); if (_min_perf < capacity) min_perf = DIV_ROUND_UP(cap_perf * _min_perf, capacity); @@ -592,74 +660,22 @@ static int amd_get_min_freq(struct amd_cpudata *cpudata) { - struct cppc_perf_caps cppc_perf; - - int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); - if (ret) - return ret; - - /* Switch to khz */ - return cppc_perf.lowest_freq * 1000; + return READ_ONCE(cpudata->min_freq); } static int amd_get_max_freq(struct amd_cpudata *cpudata) { - struct cppc_perf_caps cppc_perf; - u32 max_perf, max_freq, nominal_freq, nominal_perf; - u64 boost_ratio; - - int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); - if (ret) - return ret; - - nominal_freq = cppc_perf.nominal_freq; - nominal_perf = READ_ONCE(cpudata->nominal_perf); - max_perf = READ_ONCE(cpudata->highest_perf); - - boost_ratio = div_u64(max_perf << SCHED_CAPACITY_SHIFT, - nominal_perf); - - max_freq = nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT; - - /* Switch to khz */ - return max_freq * 1000; + return READ_ONCE(cpudata->max_freq); } static int amd_get_nominal_freq(struct amd_cpudata *cpudata) { - struct cppc_perf_caps cppc_perf; - - int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); - if (ret) - return ret; - - /* Switch to khz */ - return cppc_perf.nominal_freq * 1000; + return READ_ONCE(cpudata->nominal_freq); } static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata) { - struct cppc_perf_caps cppc_perf; - u32 lowest_nonlinear_freq, lowest_nonlinear_perf, - nominal_freq, nominal_perf; - u64 lowest_nonlinear_ratio; - - int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); - if (ret) - return ret; - - nominal_freq = cppc_perf.nominal_freq; - nominal_perf = READ_ONCE(cpudata->nominal_perf); - - lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf; - - lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT, - nominal_perf); - - lowest_nonlinear_freq = nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT; - - /* Switch to khz */ - return lowest_nonlinear_freq * 1000; + return READ_ONCE(cpudata->lowest_nonlinear_freq); } static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state) @@ -706,6 +722,61 @@ wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); } +/** + * amd_pstate_init_freq: Initialize the max_freq, min_freq, + * nominal_freq and lowest_nonlinear_freq for + * the @cpudata object. + * + * Requires: highest_perf, lowest_perf, nominal_perf and + * lowest_nonlinear_perf members of @cpudata to be + * initialized. + * + * Returns 0 on success, non-zero value on failure. + */ +static int amd_pstate_init_freq(struct amd_cpudata *cpudata) +{ + int ret; + u32 min_freq; + u32 highest_perf, max_freq; + u32 nominal_perf, nominal_freq; + u32 lowest_nonlinear_perf, lowest_nonlinear_freq; + u32 boost_ratio, lowest_nonlinear_ratio; + struct cppc_perf_caps cppc_perf; + + + ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf); + if (ret) + return ret; + + if (quirks && quirks->lowest_freq) + min_freq = quirks->lowest_freq * 1000; + else + min_freq = cppc_perf.lowest_freq * 1000; + + if (quirks && quirks->nominal_freq) + nominal_freq = quirks->nominal_freq ; + else + nominal_freq = cppc_perf.nominal_freq; + + nominal_perf = READ_ONCE(cpudata->nominal_perf); + + highest_perf = READ_ONCE(cpudata->highest_perf); + boost_ratio = div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf); + max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT) * 1000; + + lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); + lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT, + nominal_perf); + lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT) * 1000; + + WRITE_ONCE(cpudata->min_freq, min_freq); + WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq); + WRITE_ONCE(cpudata->nominal_freq, nominal_freq); + WRITE_ONCE(cpudata->max_freq, max_freq); + + return 0; +} + static int amd_pstate_cpu_init(struct cpufreq_policy *policy) { int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; @@ -731,6 +802,10 @@ if (ret) goto free_cpudata1; + ret = amd_pstate_init_freq(cpudata); + if (ret) + goto free_cpudata1; + min_freq = amd_get_min_freq(cpudata); max_freq = amd_get_max_freq(cpudata); nominal_freq = amd_get_nominal_freq(cpudata); @@ -772,13 +847,8 @@ goto free_cpudata2; } - /* Initial processor data capability frequencies */ - cpudata->max_freq = max_freq; - cpudata->min_freq = min_freq; cpudata->max_limit_freq = max_freq; cpudata->min_limit_freq = min_freq; - cpudata->nominal_freq = nominal_freq; - cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq; policy->driver_data = cpudata; @@ -1155,6 +1225,10 @@ if (ret) goto free_cpudata1; + ret = amd_pstate_init_freq(cpudata); + if (ret) + goto free_cpudata1; + min_freq = amd_get_min_freq(cpudata); max_freq = amd_get_max_freq(cpudata); nominal_freq = amd_get_nominal_freq(cpudata); @@ -1171,12 +1245,6 @@ /* It will be updated by governor */ policy->cur = policy->cpuinfo.min_freq; - /* Initial processor data capability frequencies */ - cpudata->max_freq = max_freq; - cpudata->min_freq = min_freq; - cpudata->nominal_freq = nominal_freq; - cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq; - policy->driver_data = cpudata; cpudata->epp_cached = amd_pstate_get_epp(cpudata, 0); @@ -1216,6 +1284,13 @@ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) { + struct amd_cpudata *cpudata = policy->driver_data; + + if (cpudata) { + kfree(cpudata); + policy->driver_data = NULL; + } + pr_debug("CPU %d exiting\n", policy->cpu); return 0; } @@ -1486,6 +1561,11 @@ if (cpufreq_get_current_driver()) return -EEXIST; + quirks = NULL; + + /* check if this machine need CPPC quirks */ + dmi_check_system(amd_pstate_quirks_table); + switch (cppc_state) { case AMD_PSTATE_UNDEFINED: /* Disable on the following configs by default: --- linux-xilinx-6.8.0.orig/drivers/cpufreq/amd-pstate.h +++ linux-xilinx-6.8.0/drivers/cpufreq/amd-pstate.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2022 Advanced Micro Devices, Inc. + * + * Author: Meng Li + */ + +#ifndef _LINUX_AMD_PSTATE_H +#define _LINUX_AMD_PSTATE_H + +#include + +/********************************************************************* + * AMD P-state INTERFACE * + *********************************************************************/ +/** + * struct amd_aperf_mperf + * @aperf: actual performance frequency clock count + * @mperf: maximum performance frequency clock count + * @tsc: time stamp counter + */ +struct amd_aperf_mperf { + u64 aperf; + u64 mperf; + u64 tsc; +}; + +/** + * struct amd_cpudata - private CPU data for AMD P-State + * @cpu: CPU number + * @req: constraint request to apply + * @cppc_req_cached: cached performance request hints + * @highest_perf: the maximum performance an individual processor may reach, + * assuming ideal conditions + * @nominal_perf: the maximum sustained performance level of the processor, + * assuming ideal operating conditions + * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power + * savings are achieved + * @lowest_perf: the absolute lowest performance level of the processor + * @max_freq: the frequency that mapped to highest_perf + * @min_freq: the frequency that mapped to lowest_perf + * @nominal_freq: the frequency that mapped to nominal_perf + * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf + * @cur: Difference of Aperf/Mperf/tsc count between last and current sample + * @prev: Last Aperf/Mperf/tsc count value read from register + * @freq: current cpu frequency value + * @boost_supported: check whether the Processor or SBIOS supports boost mode + * @epp_policy: Last saved policy used to set energy-performance preference + * @epp_cached: Cached CPPC energy-performance preference value + * @policy: Cpufreq policy value + * @cppc_cap1_cached Cached MSR_AMD_CPPC_CAP1 register value + * + * The amd_cpudata is key private data for each CPU thread in AMD P-State, and + * represents all the attributes and goals that AMD P-State requests at runtime. + */ +struct amd_cpudata { + int cpu; + + struct freq_qos_request req[2]; + u64 cppc_req_cached; + + u32 highest_perf; + u32 nominal_perf; + u32 lowest_nonlinear_perf; + u32 lowest_perf; + u32 min_limit_perf; + u32 max_limit_perf; + u32 min_limit_freq; + u32 max_limit_freq; + + u32 max_freq; + u32 min_freq; + u32 nominal_freq; + u32 lowest_nonlinear_freq; + + struct amd_aperf_mperf cur; + struct amd_aperf_mperf prev; + + u64 freq; + bool boost_supported; + + /* EPP feature related attributes*/ + s16 epp_policy; + s16 epp_cached; + u32 policy; + u64 cppc_cap1_cached; + bool suspended; +}; + +#endif /* _LINUX_AMD_PSTATE_H */ --- linux-xilinx-6.8.0.orig/drivers/cpufreq/brcmstb-avs-cpufreq.c +++ linux-xilinx-6.8.0/drivers/cpufreq/brcmstb-avs-cpufreq.c @@ -481,7 +481,12 @@ static unsigned int brcm_avs_cpufreq_get(unsigned int cpu) { struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - struct private_data *priv = policy->driver_data; + struct private_data *priv; + + if (!policy) + return 0; + + priv = policy->driver_data; cpufreq_cpu_put(policy); --- linux-xilinx-6.8.0.orig/drivers/cpufreq/cppc_cpufreq.c +++ linux-xilinx-6.8.0/drivers/cpufreq/cppc_cpufreq.c @@ -741,10 +741,15 @@ { struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - struct cppc_cpudata *cpu_data = policy->driver_data; + struct cppc_cpudata *cpu_data; u64 delivered_perf; int ret; + if (!policy) + return -ENODEV; + + cpu_data = policy->driver_data; + cpufreq_cpu_put(policy); ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0); @@ -822,10 +827,15 @@ static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpu) { struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - struct cppc_cpudata *cpu_data = policy->driver_data; + struct cppc_cpudata *cpu_data; u64 desired_perf; int ret; + if (!policy) + return -ENODEV; + + cpu_data = policy->driver_data; + cpufreq_cpu_put(policy); ret = cppc_get_desired_perf(cpu, &desired_perf); --- linux-xilinx-6.8.0.orig/drivers/cpufreq/cpufreq-dt.c +++ linux-xilinx-6.8.0/drivers/cpufreq/cpufreq-dt.c @@ -208,7 +208,7 @@ if (!priv) return -ENOMEM; - if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL)) + if (!zalloc_cpumask_var(&priv->cpus, GFP_KERNEL)) return -ENOMEM; cpumask_set_cpu(cpu, priv->cpus); --- linux-xilinx-6.8.0.orig/drivers/cpufreq/cpufreq.c +++ linux-xilinx-6.8.0/drivers/cpufreq/cpufreq.c @@ -644,14 +644,16 @@ if (policy->boost_enabled == enable) return count; + policy->boost_enabled = enable; + cpus_read_lock(); ret = cpufreq_driver->set_boost(policy, enable); cpus_read_unlock(); - if (ret) + if (ret) { + policy->boost_enabled = !policy->boost_enabled; return ret; - - policy->boost_enabled = enable; + } return count; } @@ -1419,6 +1421,10 @@ goto out_free_policy; } + /* Let the per-policy boost flag mirror the cpufreq_driver boost during init */ + if (cpufreq_boost_enabled() && policy_has_boost_freq(policy)) + policy->boost_enabled = true; + /* * The initialization has succeeded and the policy is online. * If there is a problem with its frequency table, take it @@ -1571,7 +1577,8 @@ if (cpufreq_driver->ready) cpufreq_driver->ready(policy); - if (cpufreq_thermal_control_enabled(cpufreq_driver)) + /* Register cpufreq cooling only for a new policy */ + if (new_policy && cpufreq_thermal_control_enabled(cpufreq_driver)) policy->cdev = of_cpufreq_cooling_register(policy); pr_debug("initialization complete\n"); @@ -1655,11 +1662,6 @@ else policy->last_policy = policy->policy; - if (cpufreq_thermal_control_enabled(cpufreq_driver)) { - cpufreq_cooling_unregister(policy->cdev); - policy->cdev = NULL; - } - if (has_target()) cpufreq_exit_governor(policy); @@ -1669,10 +1671,13 @@ */ if (cpufreq_driver->offline) { cpufreq_driver->offline(policy); - } else if (cpufreq_driver->exit) { - cpufreq_driver->exit(policy); - policy->freq_table = NULL; + return; } + + if (cpufreq_driver->exit) + cpufreq_driver->exit(policy); + + policy->freq_table = NULL; } static int cpufreq_offline(unsigned int cpu) @@ -1720,8 +1725,17 @@ return; } + /* + * Unregister cpufreq cooling once all the CPUs of the policy are + * removed. + */ + if (cpufreq_thermal_control_enabled(cpufreq_driver)) { + cpufreq_cooling_unregister(policy->cdev); + policy->cdev = NULL; + } + /* We did light-weight exit earlier, do full tear down now */ - if (cpufreq_driver->offline) + if (cpufreq_driver->offline && cpufreq_driver->exit) cpufreq_driver->exit(policy); up_write(&policy->rwsem); @@ -2755,11 +2769,12 @@ cpus_read_lock(); for_each_active_policy(policy) { + policy->boost_enabled = state; ret = cpufreq_driver->set_boost(policy, state); - if (ret) + if (ret) { + policy->boost_enabled = !policy->boost_enabled; goto err_reset_state; - - policy->boost_enabled = state; + } } cpus_read_unlock(); @@ -2841,6 +2856,20 @@ return 0; } +static char cpufreq_driver_name[CPUFREQ_NAME_LEN]; + +static int __init cpufreq_driver_setup(char *str) +{ + strscpy(cpufreq_driver_name, str, CPUFREQ_NAME_LEN); + return 1; +} + +/* + * Set this name to only allow one specific cpu freq driver, e.g., + * cpufreq_driver=powernow-k8 + */ +__setup("cpufreq_driver=", cpufreq_driver_setup); + /** * cpufreq_register_driver - register a CPU Frequency driver * @driver_data: A struct cpufreq_driver containing the values# @@ -2876,7 +2905,13 @@ (driver_data->adjust_perf && !driver_data->fast_switch)) return -EINVAL; - pr_debug("trying to register driver %s\n", driver_data->name); + pr_debug("trying to register driver %s, cpufreq_driver=%s\n", + driver_data->name, cpufreq_driver_name); + + if (cpufreq_driver_name[0]) + if (!driver_data->name || + strcmp(cpufreq_driver_name, driver_data->name)) + return -EINVAL; /* Protect against concurrent CPU online/offline. */ cpus_read_lock(); --- linux-xilinx-6.8.0.orig/drivers/cpufreq/freq_table.c +++ linux-xilinx-6.8.0/drivers/cpufreq/freq_table.c @@ -40,7 +40,7 @@ cpufreq_for_each_valid_entry(pos, table) { freq = pos->frequency; - if (!cpufreq_boost_enabled() + if ((!cpufreq_boost_enabled() || !policy->boost_enabled) && (pos->flags & CPUFREQ_BOOST_FREQ)) continue; --- linux-xilinx-6.8.0.orig/drivers/cpufreq/intel_pstate.c +++ linux-xilinx-6.8.0/drivers/cpufreq/intel_pstate.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -359,15 +360,14 @@ int ret; ret = cppc_get_perf_caps(cpu, &cppc_perf); - if (ret) - return; - /* - * On some systems with overclocking enabled, CPPC.highest_perf is hardcoded to 0xff. - * In this case we can't use CPPC.highest_perf to enable ITMT. - * In this case we can look at MSR_HWP_CAPABILITIES bits [8:0] to decide. + * If CPPC is not available, fall back to MSR_HWP_CAPABILITIES bits [8:0]. + * + * Also, on some systems with overclocking enabled, CPPC.highest_perf is + * hardcoded to 0xff, so CPPC.highest_perf cannot be used to enable ITMT. + * Fall back to MSR_HWP_CAPABILITIES then too. */ - if (cppc_perf.highest_perf == CPPC_MAX_PERF) + if (ret || cppc_perf.highest_perf == CPPC_MAX_PERF) cppc_perf.highest_perf = HWP_HIGHEST_PERF(READ_ONCE(all_cpu_data[cpu]->hwp_cap_cached)); /* @@ -2404,52 +2404,51 @@ .get_val = core_get_val, }; -#define X86_MATCH(model, policy) \ - X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ - X86_FEATURE_APERFMPERF, &policy) +#define X86_MATCH(vfm, policy) \ + X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_APERFMPERF, &policy) static const struct x86_cpu_id intel_pstate_cpu_ids[] = { - X86_MATCH(SANDYBRIDGE, core_funcs), - X86_MATCH(SANDYBRIDGE_X, core_funcs), - X86_MATCH(ATOM_SILVERMONT, silvermont_funcs), - X86_MATCH(IVYBRIDGE, core_funcs), - X86_MATCH(HASWELL, core_funcs), - X86_MATCH(BROADWELL, core_funcs), - X86_MATCH(IVYBRIDGE_X, core_funcs), - X86_MATCH(HASWELL_X, core_funcs), - X86_MATCH(HASWELL_L, core_funcs), - X86_MATCH(HASWELL_G, core_funcs), - X86_MATCH(BROADWELL_G, core_funcs), - X86_MATCH(ATOM_AIRMONT, airmont_funcs), - X86_MATCH(SKYLAKE_L, core_funcs), - X86_MATCH(BROADWELL_X, core_funcs), - X86_MATCH(SKYLAKE, core_funcs), - X86_MATCH(BROADWELL_D, core_funcs), - X86_MATCH(XEON_PHI_KNL, knl_funcs), - X86_MATCH(XEON_PHI_KNM, knl_funcs), - X86_MATCH(ATOM_GOLDMONT, core_funcs), - X86_MATCH(ATOM_GOLDMONT_PLUS, core_funcs), - X86_MATCH(SKYLAKE_X, core_funcs), - X86_MATCH(COMETLAKE, core_funcs), - X86_MATCH(ICELAKE_X, core_funcs), - X86_MATCH(TIGERLAKE, core_funcs), - X86_MATCH(SAPPHIRERAPIDS_X, core_funcs), - X86_MATCH(EMERALDRAPIDS_X, core_funcs), + X86_MATCH(INTEL_SANDYBRIDGE, core_funcs), + X86_MATCH(INTEL_SANDYBRIDGE_X, core_funcs), + X86_MATCH(INTEL_ATOM_SILVERMONT, silvermont_funcs), + X86_MATCH(INTEL_IVYBRIDGE, core_funcs), + X86_MATCH(INTEL_HASWELL, core_funcs), + X86_MATCH(INTEL_BROADWELL, core_funcs), + X86_MATCH(INTEL_IVYBRIDGE_X, core_funcs), + X86_MATCH(INTEL_HASWELL_X, core_funcs), + X86_MATCH(INTEL_HASWELL_L, core_funcs), + X86_MATCH(INTEL_HASWELL_G, core_funcs), + X86_MATCH(INTEL_BROADWELL_G, core_funcs), + X86_MATCH(INTEL_ATOM_AIRMONT, airmont_funcs), + X86_MATCH(INTEL_SKYLAKE_L, core_funcs), + X86_MATCH(INTEL_BROADWELL_X, core_funcs), + X86_MATCH(INTEL_SKYLAKE, core_funcs), + X86_MATCH(INTEL_BROADWELL_D, core_funcs), + X86_MATCH(INTEL_XEON_PHI_KNL, knl_funcs), + X86_MATCH(INTEL_XEON_PHI_KNM, knl_funcs), + X86_MATCH(INTEL_ATOM_GOLDMONT, core_funcs), + X86_MATCH(INTEL_ATOM_GOLDMONT_PLUS, core_funcs), + X86_MATCH(INTEL_SKYLAKE_X, core_funcs), + X86_MATCH(INTEL_COMETLAKE, core_funcs), + X86_MATCH(INTEL_ICELAKE_X, core_funcs), + X86_MATCH(INTEL_TIGERLAKE, core_funcs), + X86_MATCH(INTEL_SAPPHIRERAPIDS_X, core_funcs), + X86_MATCH(INTEL_EMERALDRAPIDS_X, core_funcs), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = { - X86_MATCH(BROADWELL_D, core_funcs), - X86_MATCH(BROADWELL_X, core_funcs), - X86_MATCH(SKYLAKE_X, core_funcs), - X86_MATCH(ICELAKE_X, core_funcs), - X86_MATCH(SAPPHIRERAPIDS_X, core_funcs), + X86_MATCH(INTEL_BROADWELL_D, core_funcs), + X86_MATCH(INTEL_BROADWELL_X, core_funcs), + X86_MATCH(INTEL_SKYLAKE_X, core_funcs), + X86_MATCH(INTEL_ICELAKE_X, core_funcs), + X86_MATCH(INTEL_SAPPHIRERAPIDS_X, core_funcs), {} }; static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[] = { - X86_MATCH(KABYLAKE, core_funcs), + X86_MATCH(INTEL_KABYLAKE, core_funcs), {} }; @@ -3388,14 +3387,13 @@ #define INTEL_PSTATE_HWP_BROADWELL 0x01 -#define X86_MATCH_HWP(model, hwp_mode) \ - X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ - X86_FEATURE_HWP, hwp_mode) +#define X86_MATCH_HWP(vfm, hwp_mode) \ + X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_HWP, hwp_mode) static const struct x86_cpu_id hwp_support_ids[] __initconst = { - X86_MATCH_HWP(BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL), - X86_MATCH_HWP(BROADWELL_D, INTEL_PSTATE_HWP_BROADWELL), - X86_MATCH_HWP(ANY, 0), + X86_MATCH_HWP(INTEL_BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL), + X86_MATCH_HWP(INTEL_BROADWELL_D, INTEL_PSTATE_HWP_BROADWELL), + X86_MATCH_HWP(INTEL_ANY, 0), {} }; @@ -3407,19 +3405,39 @@ return !!(value & 0x1); } -static const struct x86_cpu_id intel_epp_balance_perf[] = { +#define POWERSAVE_MASK GENMASK(7, 0) +#define BALANCE_POWER_MASK GENMASK(15, 8) +#define BALANCE_PERFORMANCE_MASK GENMASK(23, 16) +#define PERFORMANCE_MASK GENMASK(31, 24) + +#define HWP_SET_EPP_VALUES(powersave, balance_power, balance_perf, performance) \ + (FIELD_PREP_CONST(POWERSAVE_MASK, powersave) |\ + FIELD_PREP_CONST(BALANCE_POWER_MASK, balance_power) |\ + FIELD_PREP_CONST(BALANCE_PERFORMANCE_MASK, balance_perf) |\ + FIELD_PREP_CONST(PERFORMANCE_MASK, performance)) + +#define HWP_SET_DEF_BALANCE_PERF_EPP(balance_perf) \ + (HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, HWP_EPP_BALANCE_POWERSAVE,\ + balance_perf, HWP_EPP_PERFORMANCE)) + +static const struct x86_cpu_id intel_epp_default[] = { /* * Set EPP value as 102, this is the max suggested EPP * which can result in one core turbo frequency for * AlderLake Mobile CPUs. */ - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 102), - X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 32), + X86_MATCH_VFM(INTEL_ALDERLAKE_L, HWP_SET_DEF_BALANCE_PERF_EPP(102)), + X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), + X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)), + X86_MATCH_VFM(INTEL_METEORLAKE_L, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, + 179, 64, 16)), + X86_MATCH_VFM(INTEL_ARROWLAKE, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, + 179, 64, 16)), {} }; static const struct x86_cpu_id intel_hybrid_scaling_factor[] = { - X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, HYBRID_SCALING_FACTOR_MTL), + X86_MATCH_VFM(INTEL_METEORLAKE_L, HYBRID_SCALING_FACTOR_MTL), {} }; @@ -3512,11 +3530,24 @@ intel_pstate_sysfs_expose_params(); if (hwp_active) { - const struct x86_cpu_id *id = x86_match_cpu(intel_epp_balance_perf); + const struct x86_cpu_id *id = x86_match_cpu(intel_epp_default); const struct x86_cpu_id *hybrid_id = x86_match_cpu(intel_hybrid_scaling_factor); - if (id) - epp_values[EPP_INDEX_BALANCE_PERFORMANCE] = id->driver_data; + if (id) { + epp_values[EPP_INDEX_POWERSAVE] = + FIELD_GET(POWERSAVE_MASK, id->driver_data); + epp_values[EPP_INDEX_BALANCE_POWERSAVE] = + FIELD_GET(BALANCE_POWER_MASK, id->driver_data); + epp_values[EPP_INDEX_BALANCE_PERFORMANCE] = + FIELD_GET(BALANCE_PERFORMANCE_MASK, id->driver_data); + epp_values[EPP_INDEX_PERFORMANCE] = + FIELD_GET(PERFORMANCE_MASK, id->driver_data); + pr_debug("Updated EPPs powersave:%x balanced power:%x balanced perf:%x performance:%x\n", + epp_values[EPP_INDEX_POWERSAVE], + epp_values[EPP_INDEX_BALANCE_POWERSAVE], + epp_values[EPP_INDEX_BALANCE_PERFORMANCE], + epp_values[EPP_INDEX_PERFORMANCE]); + } if (hybrid_id) { hybrid_scaling_factor = hybrid_id->driver_data; --- linux-xilinx-6.8.0.orig/drivers/cpufreq/mediatek-cpufreq-hw.c +++ linux-xilinx-6.8.0/drivers/cpufreq/mediatek-cpufreq-hw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define LUT_MAX_ENTRIES 32U @@ -300,7 +301,23 @@ static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev) { const void *data; - int ret; + int ret, cpu; + struct device *cpu_dev; + struct regulator *cpu_reg; + + /* Make sure that all CPU supplies are available before proceeding. */ + for_each_possible_cpu(cpu) { + cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) + return dev_err_probe(&pdev->dev, -EPROBE_DEFER, + "Failed to get cpu%d device\n", cpu); + + cpu_reg = devm_regulator_get(cpu_dev, "cpu"); + if (IS_ERR(cpu_reg)) + return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg), + "CPU%d regulator get failed\n", cpu); + } + data = of_device_get_match_data(&pdev->dev); if (!data) --- linux-xilinx-6.8.0.orig/drivers/cpuidle/driver.c +++ linux-xilinx-6.8.0/drivers/cpuidle/driver.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "cpuidle.h" @@ -187,7 +188,7 @@ s->target_residency = div_u64(s->target_residency_ns, NSEC_PER_USEC); if (s->exit_latency > 0) - s->exit_latency_ns = s->exit_latency * NSEC_PER_USEC; + s->exit_latency_ns = mul_u32_u32(s->exit_latency, NSEC_PER_USEC); else if (s->exit_latency_ns < 0) s->exit_latency_ns = 0; else --- linux-xilinx-6.8.0.orig/drivers/crypto/Kconfig +++ linux-xilinx-6.8.0/drivers/crypto/Kconfig @@ -660,6 +660,27 @@ This will create /sys/kernel/debug/rk3288_crypto/stats for displaying the number of requests per algorithm and other internal stats. +config CRYPTO_DEV_XILINX_ECDSA + tristate "Support for Xilinx ECDSA hardware accelerator" + depends on ARCH_ZYNQMP || COMPILE_TEST + select CRYPTO_ENGINE + select CRYPTO_AKCIPHER + select CRYPTO_ECDSA + help + Xilinx processors have ECDSA hardware accelerator used for signature + and key generation and verification. This driver interfaces with + ECDSA hardware accelerator. Select this if you want to use the Versal + module for ECDSA algorithms. + +config CRYPTO_DEV_XILINX_RSA + tristate "Support for Xilinx ZynqMP RSA hw accelerator (DEPRECATED)" + depends on (ARCH_ZYNQMP || COMPILE_TEST) && (CRYPTO_DEV_XILINX_RSA_AKCIPHER=n) + select CRYPTO_AES + select CRYPTO_BLKCIPHER + help + Xilinx processors have RSA hw accelerator used for signature + generation and verification. This driver is deprecated. + Please migrate to : CRYPTO_DEV_XILINX_RSA_AKCIPHER config CRYPTO_DEV_ZYNQMP_AES tristate "Support for Xilinx ZynqMP AES hw accelerator" @@ -667,6 +688,8 @@ select CRYPTO_AES select CRYPTO_ENGINE select CRYPTO_AEAD + select CRYPTO_GCM + select CRYPTO_USER_API_AEAD help Xilinx ZynqMP has AES-GCM engine used for symmetric key encryption and decryption. This driver interfaces with AES hw @@ -683,6 +706,18 @@ Select this if you want to use the ZynqMP module for SHA3 hash computation. +config CRYPTO_DEV_XILINX_RSA_AKCIPHER + tristate "Support for Xilinx RSA hw accelerator" + depends on ARCH_ZYNQMP || COMPILE_TEST + select CRYPTO_ENGINE + select CRYPTO_RSA + select CRYPTO_AKCIPHER + help + Xilinx processors have RSA hw accelerator used for signature + generation and verification. This driver interfaces with RSA + hw accelerator. Select this if you want to use ZynqMP or Versal + module for RSA algorithms. + source "drivers/crypto/chelsio/Kconfig" source "drivers/crypto/virtio/Kconfig" --- linux-xilinx-6.8.0.orig/drivers/crypto/bcm/spu2.c +++ linux-xilinx-6.8.0/drivers/crypto/bcm/spu2.c @@ -495,7 +495,7 @@ if (hash_iv_len) { packet_log(" Hash IV Length %u bytes\n", hash_iv_len); packet_dump(" hash IV: ", ptr, hash_iv_len); - ptr += ciph_key_len; + ptr += hash_iv_len; } if (ciph_iv_len) { --- linux-xilinx-6.8.0.orig/drivers/crypto/ccp/platform-access.c +++ linux-xilinx-6.8.0/drivers/crypto/ccp/platform-access.c @@ -118,9 +118,16 @@ goto unlock; } - /* Store the status in request header for caller to investigate */ + /* + * Read status from PSP. If status is non-zero, it indicates an error + * occurred during "processing" of the command. + * If status is zero, it indicates the command was "processed" + * successfully, but the result of the command is in the payload. + * Return both cases to the caller as -EIO to investigate. + */ cmd_reg = ioread32(cmd); - req->header.status = FIELD_GET(PSP_CMDRESP_STS, cmd_reg); + if (FIELD_GET(PSP_CMDRESP_STS, cmd_reg)) + req->header.status = FIELD_GET(PSP_CMDRESP_STS, cmd_reg); if (req->header.status) { ret = -EIO; goto unlock; --- linux-xilinx-6.8.0.orig/drivers/crypto/ccp/sp-platform.c +++ linux-xilinx-6.8.0/drivers/crypto/ccp/sp-platform.c @@ -39,44 +39,38 @@ }, }; -#ifdef CONFIG_ACPI static const struct acpi_device_id sp_acpi_match[] = { { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] }, { }, }; MODULE_DEVICE_TABLE(acpi, sp_acpi_match); -#endif -#ifdef CONFIG_OF static const struct of_device_id sp_of_match[] = { { .compatible = "amd,ccp-seattle-v1a", .data = (const void *)&dev_vdata[0] }, { }, }; MODULE_DEVICE_TABLE(of, sp_of_match); -#endif static struct sp_dev_vdata *sp_get_of_version(struct platform_device *pdev) { -#ifdef CONFIG_OF const struct of_device_id *match; match = of_match_node(sp_of_match, pdev->dev.of_node); if (match && match->data) return (struct sp_dev_vdata *)match->data; -#endif + return NULL; } static struct sp_dev_vdata *sp_get_acpi_version(struct platform_device *pdev) { -#ifdef CONFIG_ACPI const struct acpi_device_id *match; match = acpi_match_device(sp_acpi_match, &pdev->dev); if (match && match->driver_data) return (struct sp_dev_vdata *)match->driver_data; -#endif + return NULL; } @@ -212,12 +206,8 @@ static struct platform_driver sp_platform_driver = { .driver = { .name = "ccp", -#ifdef CONFIG_ACPI .acpi_match_table = sp_acpi_match, -#endif -#ifdef CONFIG_OF .of_match_table = sp_of_match, -#endif }, .probe = sp_platform_probe, .remove_new = sp_platform_remove, --- linux-xilinx-6.8.0.orig/drivers/crypto/hisilicon/debugfs.c +++ linux-xilinx-6.8.0/drivers/crypto/hisilicon/debugfs.c @@ -783,8 +783,14 @@ { int i; + if (!dregs) + return; + /* Setting the pointer is NULL to prevent double free */ for (i = 0; i < reg_len; i++) { + if (!dregs[i].regs) + continue; + kfree(dregs[i].regs); dregs[i].regs = NULL; } @@ -834,14 +840,21 @@ static int qm_diff_regs_init(struct hisi_qm *qm, struct dfx_diff_registers *dregs, u32 reg_len) { + int ret; + qm->debug.qm_diff_regs = dfx_regs_init(qm, qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); - if (IS_ERR(qm->debug.qm_diff_regs)) - return PTR_ERR(qm->debug.qm_diff_regs); + if (IS_ERR(qm->debug.qm_diff_regs)) { + ret = PTR_ERR(qm->debug.qm_diff_regs); + qm->debug.qm_diff_regs = NULL; + return ret; + } qm->debug.acc_diff_regs = dfx_regs_init(qm, dregs, reg_len); if (IS_ERR(qm->debug.acc_diff_regs)) { dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); - return PTR_ERR(qm->debug.acc_diff_regs); + ret = PTR_ERR(qm->debug.acc_diff_regs); + qm->debug.acc_diff_regs = NULL; + return ret; } return 0; @@ -882,7 +895,9 @@ static void qm_diff_regs_uninit(struct hisi_qm *qm, u32 reg_len) { dfx_regs_uninit(qm, qm->debug.acc_diff_regs, reg_len); + qm->debug.acc_diff_regs = NULL; dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs)); + qm->debug.qm_diff_regs = NULL; } /** --- linux-xilinx-6.8.0.orig/drivers/crypto/hisilicon/qm.c +++ linux-xilinx-6.8.0/drivers/crypto/hisilicon/qm.c @@ -2833,12 +2833,9 @@ hisi_qm_set_state(qm, QM_NOT_READY); up_write(&qm->qps_lock); + qm_remove_uacce(qm); qm_irqs_unregister(qm); hisi_qm_pci_uninit(qm); - if (qm->use_sva) { - uacce_remove(qm->uacce); - qm->uacce = NULL; - } } EXPORT_SYMBOL_GPL(hisi_qm_uninit); --- linux-xilinx-6.8.0.orig/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ linux-xilinx-6.8.0/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -481,8 +481,10 @@ if (ctx->pbuf_supported) sec_free_pbuf_resource(dev, qp_ctx->res); - if (ctx->alg_type == SEC_AEAD) + if (ctx->alg_type == SEC_AEAD) { sec_free_mac_resource(dev, qp_ctx->res); + sec_free_aiv_resource(dev, qp_ctx->res); + } } static int sec_alloc_qp_ctx_resource(struct hisi_qm *qm, struct sec_ctx *ctx, --- linux-xilinx-6.8.0.orig/drivers/crypto/hisilicon/sec2/sec_main.c +++ linux-xilinx-6.8.0/drivers/crypto/hisilicon/sec2/sec_main.c @@ -152,7 +152,7 @@ {SEC_CORE_TYPE_NUM_CAP, 0x313c, 16, GENMASK(3, 0), 0x1, 0x1, 0x1}, {SEC_CORE_NUM_CAP, 0x313c, 8, GENMASK(7, 0), 0x4, 0x4, 0x4}, {SEC_CORES_PER_CLUSTER_NUM_CAP, 0x313c, 0, GENMASK(7, 0), 0x4, 0x4, 0x4}, - {SEC_CORE_ENABLE_BITMAP, 0x3140, 32, GENMASK(31, 0), 0x17F, 0x17F, 0xF}, + {SEC_CORE_ENABLE_BITMAP, 0x3140, 0, GENMASK(31, 0), 0x17F, 0x17F, 0xF}, {SEC_DRV_ALG_BITMAP_LOW, 0x3144, 0, GENMASK(31, 0), 0x18050CB, 0x18050CB, 0x18670CF}, {SEC_DRV_ALG_BITMAP_HIGH, 0x3148, 0, GENMASK(31, 0), 0x395C, 0x395C, 0x395C}, {SEC_DEV_ALG_BITMAP_LOW, 0x314c, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/iaa/iaa_crypto_main.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/iaa/iaa_crypto_main.c @@ -908,6 +908,8 @@ return -EINVAL; cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa; + if (!cpus_per_iaa) + cpus_per_iaa = 1; out: return 0; } @@ -923,10 +925,12 @@ } } - if (nr_iaa) + if (nr_iaa) { cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa; - else - cpus_per_iaa = 0; + if (!cpus_per_iaa) + cpus_per_iaa = 1; + } else + cpus_per_iaa = 1; } static int wq_table_add_wqs(int iaa, int cpu) @@ -1324,7 +1328,7 @@ *compression_crc = idxd_desc->iax_completion->crc; - if (!ctx->async_mode) + if (!ctx->async_mode || disable_async) idxd_free_desc(wq, idxd_desc); out: return ret; @@ -1570,7 +1574,7 @@ *dlen = req->dlen; - if (!ctx->async_mode) + if (!ctx->async_mode || disable_async) idxd_free_desc(wq, idxd_desc); /* Update stats */ --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/Kconfig +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/Kconfig @@ -106,3 +106,17 @@ To compile this as a module, choose M here: the module will be called qat_c62xvf. + +config CRYPTO_DEV_QAT_ERROR_INJECTION + bool "Support for Intel(R) QAT Devices Heartbeat Error Injection" + depends on CRYPTO_DEV_QAT + depends on DEBUG_FS + help + Enables a mechanism that allows to inject a heartbeat error on + Intel(R) QuickAssist devices for testing purposes. + + This is intended for developer use only. + If unsure, say N. + + This functionality is available via debugfs entry of the Intel(R) + QuickAssist device --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c @@ -296,7 +296,7 @@ { if (adf_gen4_init_thd2arb_map(accel_dev)) dev_warn(&GET_DEV(accel_dev), - "Generate of the thread to arbiter map failed"); + "Failed to generate thread to arbiter mapping"); return GET_HW_DATA(accel_dev)->thd_to_arb_map; } @@ -372,6 +372,13 @@ if (!fw_config) return 0; + /* If dcc, all rings handle compression requests */ + if (adf_get_service_enabled(accel_dev) == SVC_DCC) { + for (i = 0; i < RP_GROUP_COUNT; i++) + rps[i] = COMP; + goto set_mask; + } + for (i = 0; i < RP_GROUP_COUNT; i++) { switch (fw_config[i].ae_mask) { case ADF_AE_GROUP_0: @@ -400,6 +407,7 @@ } } +set_mask: ring_to_svc_map = rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_0_SHIFT | rps[RP_GROUP_1] << ADF_CFG_SERV_RING_PAIR_1_SHIFT | rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_2_SHIFT | --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c @@ -208,7 +208,7 @@ { if (adf_gen4_init_thd2arb_map(accel_dev)) dev_warn(&GET_DEV(accel_dev), - "Generate of the thread to arbiter map failed"); + "Failed to generate thread to arbiter mapping"); return GET_HW_DATA(accel_dev)->thd_to_arb_map; } @@ -331,6 +331,13 @@ if (!fw_config) return 0; + /* If dcc, all rings handle compression requests */ + if (adf_get_service_enabled(accel_dev) == SVC_DCC) { + for (i = 0; i < RP_GROUP_COUNT; i++) + rps[i] = COMP; + goto set_mask; + } + for (i = 0; i < RP_GROUP_COUNT; i++) { switch (fw_config[i].ae_mask) { case ADF_AE_GROUP_0: @@ -359,6 +366,7 @@ } } +set_mask: ring_to_svc_map = rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_0_SHIFT | rps[RP_GROUP_1] << ADF_CFG_SERV_RING_PAIR_1_SHIFT | rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_2_SHIFT | --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c @@ -197,7 +197,9 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Intel"); MODULE_FIRMWARE(ADF_4XXX_FW); +MODULE_FIRMWARE(ADF_402XX_FW); MODULE_FIRMWARE(ADF_4XXX_MMP); +MODULE_FIRMWARE(ADF_402XX_MMP); MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); MODULE_VERSION(ADF_DRV_VERSION); MODULE_SOFTDEP("pre: crypto-intel_qat"); --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/Makefile +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/Makefile @@ -53,3 +53,5 @@ adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \ adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \ adf_gen2_pfvf.o adf_gen4_pfvf.o + +intel_qat-$(CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION) += adf_heartbeat_inject.o --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h @@ -332,6 +332,7 @@ struct ratelimit_state vf2pf_ratelimit; u32 vf_nr; bool init; + bool restarting; u8 vf_compat_ver; }; @@ -401,6 +402,7 @@ struct adf_error_counters ras_errors; struct mutex state_lock; /* protect state of the device */ bool is_vf; + bool autoreset_on_error; u32 accel_id; }; #endif --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_aer.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_aer.c @@ -7,8 +7,15 @@ #include #include "adf_accel_devices.h" #include "adf_common_drv.h" +#include "adf_pfvf_pf_msg.h" + +struct adf_fatal_error_data { + struct adf_accel_dev *accel_dev; + struct work_struct work; +}; static struct workqueue_struct *device_reset_wq; +static struct workqueue_struct *device_sriov_wq; static pci_ers_result_t adf_error_detected(struct pci_dev *pdev, pci_channel_state_t state) @@ -26,6 +33,19 @@ return PCI_ERS_RESULT_DISCONNECT; } + set_bit(ADF_STATUS_RESTARTING, &accel_dev->status); + if (accel_dev->hw_device->exit_arb) { + dev_dbg(&pdev->dev, "Disabling arbitration\n"); + accel_dev->hw_device->exit_arb(accel_dev); + } + adf_error_notifier(accel_dev); + adf_pf2vf_notify_fatal_error(accel_dev); + adf_dev_restarting_notify(accel_dev); + adf_pf2vf_notify_restarting(accel_dev); + adf_pf2vf_wait_for_restarting_complete(accel_dev); + pci_clear_master(pdev); + adf_dev_down(accel_dev, false); + return PCI_ERS_RESULT_NEED_RESET; } @@ -37,6 +57,13 @@ struct work_struct reset_work; }; +/* sriov dev data */ +struct adf_sriov_dev_data { + struct adf_accel_dev *accel_dev; + struct completion compl; + struct work_struct sriov_work; +}; + void adf_reset_sbr(struct adf_accel_dev *accel_dev) { struct pci_dev *pdev = accel_to_pci_dev(accel_dev); @@ -82,11 +109,22 @@ } } +static void adf_device_sriov_worker(struct work_struct *work) +{ + struct adf_sriov_dev_data *sriov_data = + container_of(work, struct adf_sriov_dev_data, sriov_work); + + adf_reenable_sriov(sriov_data->accel_dev); + complete(&sriov_data->compl); +} + static void adf_device_reset_worker(struct work_struct *work) { struct adf_reset_dev_data *reset_data = container_of(work, struct adf_reset_dev_data, reset_work); struct adf_accel_dev *accel_dev = reset_data->accel_dev; + unsigned long wait_jiffies = msecs_to_jiffies(10000); + struct adf_sriov_dev_data sriov_data; adf_dev_restarting_notify(accel_dev); if (adf_dev_restart(accel_dev)) { @@ -97,14 +135,22 @@ WARN(1, "QAT: device restart failed. Device is unusable\n"); return; } + + sriov_data.accel_dev = accel_dev; + init_completion(&sriov_data.compl); + INIT_WORK(&sriov_data.sriov_work, adf_device_sriov_worker); + queue_work(device_sriov_wq, &sriov_data.sriov_work); + if (wait_for_completion_timeout(&sriov_data.compl, wait_jiffies)) + adf_pf2vf_notify_restarted(accel_dev); + adf_dev_restarted_notify(accel_dev); clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); /* The dev is back alive. Notify the caller if in sync mode */ - if (reset_data->mode == ADF_DEV_RESET_SYNC) - complete(&reset_data->compl); - else + if (reset_data->mode == ADF_DEV_RESET_ASYNC) kfree(reset_data); + else + complete(&reset_data->compl); } static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, @@ -136,6 +182,7 @@ if (!timeout) { dev_err(&GET_DEV(accel_dev), "Reset device timeout expired\n"); + cancel_work_sync(&reset_data->reset_work); ret = -EFAULT; } kfree(reset_data); @@ -147,14 +194,25 @@ static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev) { struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); + int res = 0; if (!accel_dev) { pr_err("QAT: Can't find acceleration device\n"); return PCI_ERS_RESULT_DISCONNECT; } - if (adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_SYNC)) + + if (!pdev->is_busmaster) + pci_set_master(pdev); + pci_restore_state(pdev); + pci_save_state(pdev); + res = adf_dev_up(accel_dev, false); + if (res && res != -EALREADY) return PCI_ERS_RESULT_DISCONNECT; + adf_reenable_sriov(accel_dev); + adf_pf2vf_notify_restarted(accel_dev); + adf_dev_restarted_notify(accel_dev); + clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); return PCI_ERS_RESULT_RECOVERED; } @@ -171,11 +229,62 @@ }; EXPORT_SYMBOL_GPL(adf_err_handler); +int adf_dev_autoreset(struct adf_accel_dev *accel_dev) +{ + if (accel_dev->autoreset_on_error) + return adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_ASYNC); + + return 0; +} + +static void adf_notify_fatal_error_worker(struct work_struct *work) +{ + struct adf_fatal_error_data *wq_data = + container_of(work, struct adf_fatal_error_data, work); + struct adf_accel_dev *accel_dev = wq_data->accel_dev; + struct adf_hw_device_data *hw_device = accel_dev->hw_device; + + adf_error_notifier(accel_dev); + + if (!accel_dev->is_vf) { + /* Disable arbitration to stop processing of new requests */ + if (accel_dev->autoreset_on_error && hw_device->exit_arb) + hw_device->exit_arb(accel_dev); + if (accel_dev->pf.vf_info) + adf_pf2vf_notify_fatal_error(accel_dev); + adf_dev_autoreset(accel_dev); + } + + kfree(wq_data); +} + +int adf_notify_fatal_error(struct adf_accel_dev *accel_dev) +{ + struct adf_fatal_error_data *wq_data; + + wq_data = kzalloc(sizeof(*wq_data), GFP_ATOMIC); + if (!wq_data) + return -ENOMEM; + + wq_data->accel_dev = accel_dev; + INIT_WORK(&wq_data->work, adf_notify_fatal_error_worker); + adf_misc_wq_queue_work(&wq_data->work); + + return 0; +} + int adf_init_aer(void) { device_reset_wq = alloc_workqueue("qat_device_reset_wq", WQ_MEM_RECLAIM, 0); - return !device_reset_wq ? -EFAULT : 0; + if (!device_reset_wq) + return -EFAULT; + + device_sriov_wq = alloc_workqueue("qat_device_sriov_wq", 0, 0); + if (!device_sriov_wq) + return -EFAULT; + + return 0; } void adf_exit_aer(void) @@ -183,4 +292,8 @@ if (device_reset_wq) destroy_workqueue(device_reset_wq); device_reset_wq = NULL; + + if (device_sriov_wq) + destroy_workqueue(device_sriov_wq); + device_sriov_wq = NULL; } --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h @@ -49,5 +49,6 @@ ADF_ETRMGR_BANK "%d" ADF_ETRMGR_CORE_AFFINITY #define ADF_ACCEL_STR "Accelerator%d" #define ADF_HEARTBEAT_TIMER "HeartbeatTimer" +#define ADF_SRIOV_ENABLED "SriovEnabled" #endif --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_clock.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_clock.c @@ -83,6 +83,9 @@ } delta_us = timespec_to_us(&ts3) - timespec_to_us(&ts1); + if (!delta_us) + return -EINVAL; + temp = (timestamp2 - timestamp1) * ME_CLK_DIVIDER * 10; temp = DIV_ROUND_CLOSEST_ULL(temp, delta_us); /* --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_cnv_dbgfs.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_cnv_dbgfs.c @@ -16,7 +16,6 @@ #define CNV_ERR_INFO_MASK GENMASK(11, 0) #define CNV_ERR_TYPE_MASK GENMASK(15, 12) -#define CNV_SLICE_ERR_MASK GENMASK(7, 0) #define CNV_SLICE_ERR_SIGN_BIT_INDEX 7 #define CNV_DELTA_ERR_SIGN_BIT_INDEX 11 --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_common_drv.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_common_drv.h @@ -40,6 +40,7 @@ ADF_EVENT_SHUTDOWN, ADF_EVENT_RESTARTING, ADF_EVENT_RESTARTED, + ADF_EVENT_FATAL_ERROR, }; struct service_hndl { @@ -60,6 +61,8 @@ void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data); void adf_clean_vf_map(bool); +int adf_notify_fatal_error(struct adf_accel_dev *accel_dev); +void adf_error_notifier(struct adf_accel_dev *accel_dev); int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, struct adf_accel_dev *pf); void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev, @@ -84,12 +87,14 @@ extern const struct pci_error_handlers adf_err_handler; void adf_reset_sbr(struct adf_accel_dev *accel_dev); void adf_reset_flr(struct adf_accel_dev *accel_dev); +int adf_dev_autoreset(struct adf_accel_dev *accel_dev); void adf_dev_restore(struct adf_accel_dev *accel_dev); int adf_init_aer(void); void adf_exit_aer(void); int adf_init_arb(struct adf_accel_dev *accel_dev); void adf_exit_arb(struct adf_accel_dev *accel_dev); void adf_update_ring_arb(struct adf_etr_ring_data *ring); +int adf_disable_arb_thd(struct adf_accel_dev *accel_dev, u32 ae, u32 thr); int adf_dev_get(struct adf_accel_dev *accel_dev); void adf_dev_put(struct adf_accel_dev *accel_dev); @@ -188,6 +193,7 @@ #if defined(CONFIG_PCI_IOV) int adf_sriov_configure(struct pci_dev *pdev, int numvfs); void adf_disable_sriov(struct adf_accel_dev *accel_dev); +void adf_reenable_sriov(struct adf_accel_dev *accel_dev); void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask); void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev); bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev); @@ -208,6 +214,10 @@ { } +static inline void adf_reenable_sriov(struct adf_accel_dev *accel_dev) +{ +} + static inline int adf_init_pf_wq(void) { return 0; --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c @@ -398,6 +398,9 @@ ADF_GEN4_ADMIN_ACCELENGINES; if (srv_id == SVC_DCC) { + if (ae_cnt > ICP_QAT_HW_AE_DELIMITER) + return -EINVAL; + memcpy(thd2arb_map, thrd_to_arb_map_dcc, array_size(sizeof(*thd2arb_map), ae_cnt)); return 0; --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c @@ -1007,8 +1007,7 @@ static bool adf_handle_ssmcpppar_err(struct adf_accel_dev *accel_dev, void __iomem *csr, u32 iastatssm) { - u32 reg = ADF_CSR_RD(csr, ADF_GEN4_SSMCPPERR); - u32 bits_num = BITS_PER_REG(reg); + u32 reg, bits_num = BITS_PER_REG(reg); bool reset_required = false; unsigned long errs_bits; u32 bit_iterator; @@ -1106,8 +1105,7 @@ static bool adf_handle_ser_err_ssmsh(struct adf_accel_dev *accel_dev, void __iomem *csr, u32 iastatssm) { - u32 reg = ADF_CSR_RD(csr, ADF_GEN4_SER_ERR_SSMSH); - u32 bits_num = BITS_PER_REG(reg); + u32 reg, bits_num = BITS_PER_REG(reg); bool reset_required = false; unsigned long errs_bits; u32 bit_iterator; --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen4_tl.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen4_tl.c @@ -149,5 +149,6 @@ tl_data->sl_exec_counters = sl_exec_counters; tl_data->rp_counters = rp_counters; tl_data->num_rp_counters = ARRAY_SIZE(rp_counters); + tl_data->max_sl_cnt = ADF_GEN4_TL_MAX_SLICES_PER_TYPE; } EXPORT_SYMBOL_GPL(adf_gen4_init_tl_data); --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c @@ -23,12 +23,6 @@ #define ADF_HB_EMPTY_SIG 0xA5A5A5A5 -/* Heartbeat counter pair */ -struct hb_cnt_pair { - __u16 resp_heartbeat_cnt; - __u16 req_heartbeat_cnt; -}; - static int adf_hb_check_polling_freq(struct adf_accel_dev *accel_dev) { u64 curr_time = adf_clock_get_current_time(); @@ -211,6 +205,19 @@ return ret; } +static void adf_heartbeat_reset(struct adf_accel_dev *accel_dev) +{ + u64 curr_time = adf_clock_get_current_time(); + u64 time_since_reset = curr_time - accel_dev->heartbeat->last_hb_reset_time; + + if (time_since_reset < ADF_CFG_HB_RESET_MS) + return; + + accel_dev->heartbeat->last_hb_reset_time = curr_time; + if (adf_notify_fatal_error(accel_dev)) + dev_err(&GET_DEV(accel_dev), "Failed to notify fatal error\n"); +} + void adf_heartbeat_status(struct adf_accel_dev *accel_dev, enum adf_device_heartbeat_status *hb_status) { @@ -235,6 +242,7 @@ "Heartbeat ERROR: QAT is not responding.\n"); *hb_status = HB_DEV_UNRESPONSIVE; hb->hb_failed_counter++; + adf_heartbeat_reset(accel_dev); return; } --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat.h @@ -13,17 +13,26 @@ #define ADF_CFG_HB_TIMER_DEFAULT_MS 500 #define ADF_CFG_HB_COUNT_THRESHOLD 3 +#define ADF_CFG_HB_RESET_MS 5000 + enum adf_device_heartbeat_status { HB_DEV_UNRESPONSIVE = 0, HB_DEV_ALIVE, HB_DEV_UNSUPPORTED, }; +/* Heartbeat counter pair */ +struct hb_cnt_pair { + __u16 resp_heartbeat_cnt; + __u16 req_heartbeat_cnt; +}; + struct adf_heartbeat { unsigned int hb_sent_counter; unsigned int hb_failed_counter; unsigned int hb_timer; u64 last_hb_check_time; + u64 last_hb_reset_time; bool ctrs_cnt_checked; struct hb_dma_addr { dma_addr_t phy_addr; @@ -35,6 +44,9 @@ struct dentry *cfg; struct dentry *sent; struct dentry *failed; +#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION + struct dentry *inject_error; +#endif } dbgfs; }; @@ -51,6 +63,15 @@ enum adf_device_heartbeat_status *hb_status); void adf_heartbeat_check_ctrs(struct adf_accel_dev *accel_dev); +#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION +int adf_heartbeat_inject_error(struct adf_accel_dev *accel_dev); +#else +static inline int adf_heartbeat_inject_error(struct adf_accel_dev *accel_dev) +{ + return -EPERM; +} +#endif + #else static inline int adf_heartbeat_init(struct adf_accel_dev *accel_dev) { --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat_dbgfs.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat_dbgfs.c @@ -155,6 +155,43 @@ .write = adf_hb_cfg_write, }; +static ssize_t adf_hb_error_inject_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct adf_accel_dev *accel_dev = file->private_data; + size_t written_chars; + char buf[3]; + int ret; + + /* last byte left as string termination */ + if (count != 2) + return -EINVAL; + + written_chars = simple_write_to_buffer(buf, sizeof(buf) - 1, + ppos, user_buf, count); + if (buf[0] != '1') + return -EINVAL; + + ret = adf_heartbeat_inject_error(accel_dev); + if (ret) { + dev_err(&GET_DEV(accel_dev), + "Heartbeat error injection failed with status %d\n", + ret); + return ret; + } + + dev_info(&GET_DEV(accel_dev), "Heartbeat error injection enabled\n"); + + return written_chars; +} + +static const struct file_operations adf_hb_error_inject_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = adf_hb_error_inject_write, +}; + void adf_heartbeat_dbgfs_add(struct adf_accel_dev *accel_dev) { struct adf_heartbeat *hb = accel_dev->heartbeat; @@ -171,6 +208,17 @@ &hb->hb_failed_counter, &adf_hb_stats_fops); hb->dbgfs.cfg = debugfs_create_file("config", 0600, hb->dbgfs.base_dir, accel_dev, &adf_hb_cfg_fops); + + if (IS_ENABLED(CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION)) { + struct dentry *inject_error __maybe_unused; + + inject_error = debugfs_create_file("inject_error", 0200, + hb->dbgfs.base_dir, accel_dev, + &adf_hb_error_inject_fops); +#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION + hb->dbgfs.inject_error = inject_error; +#endif + } } EXPORT_SYMBOL_GPL(adf_heartbeat_dbgfs_add); @@ -189,6 +237,10 @@ hb->dbgfs.failed = NULL; debugfs_remove(hb->dbgfs.cfg); hb->dbgfs.cfg = NULL; +#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION + debugfs_remove(hb->dbgfs.inject_error); + hb->dbgfs.inject_error = NULL; +#endif debugfs_remove(hb->dbgfs.base_dir); hb->dbgfs.base_dir = NULL; } --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat_inject.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat_inject.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2023 Intel Corporation */ +#include + +#include "adf_admin.h" +#include "adf_common_drv.h" +#include "adf_heartbeat.h" + +#define MAX_HB_TICKS 0xFFFFFFFF + +static int adf_hb_set_timer_to_max(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + + accel_dev->heartbeat->hb_timer = 0; + + if (hw_data->stop_timer) + hw_data->stop_timer(accel_dev); + + return adf_send_admin_hb_timer(accel_dev, MAX_HB_TICKS); +} + +static void adf_set_hb_counters_fail(struct adf_accel_dev *accel_dev, u32 ae, + u32 thr) +{ + struct hb_cnt_pair *stats = accel_dev->heartbeat->dma.virt_addr; + struct adf_hw_device_data *hw_device = accel_dev->hw_device; + const size_t max_aes = hw_device->get_num_aes(hw_device); + const size_t hb_ctrs = hw_device->num_hb_ctrs; + size_t thr_id = ae * hb_ctrs + thr; + u16 num_rsp = stats[thr_id].resp_heartbeat_cnt; + + /* + * Inject live.req != live.rsp and live.rsp == last.rsp + * to trigger the heartbeat error detection + */ + stats[thr_id].req_heartbeat_cnt++; + stats += (max_aes * hb_ctrs); + stats[thr_id].resp_heartbeat_cnt = num_rsp; +} + +int adf_heartbeat_inject_error(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_device = accel_dev->hw_device; + const size_t max_aes = hw_device->get_num_aes(hw_device); + const size_t hb_ctrs = hw_device->num_hb_ctrs; + u32 rand, rand_ae, rand_thr; + unsigned long ae_mask; + int ret; + + ae_mask = hw_device->ae_mask; + + do { + /* Ensure we have a valid ae */ + get_random_bytes(&rand, sizeof(rand)); + rand_ae = rand % max_aes; + } while (!test_bit(rand_ae, &ae_mask)); + + get_random_bytes(&rand, sizeof(rand)); + rand_thr = rand % hb_ctrs; + + /* Increase the heartbeat timer to prevent FW updating HB counters */ + ret = adf_hb_set_timer_to_max(accel_dev); + if (ret) + return ret; + + /* Configure worker threads to stop processing any packet */ + ret = adf_disable_arb_thd(accel_dev, rand_ae, rand_thr); + if (ret) + return ret; + + /* Change HB counters memory to simulate a hang */ + adf_set_hb_counters_fail(accel_dev, rand_ae, rand_thr); + + return 0; +} --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c @@ -103,3 +103,28 @@ csr_ops->write_csr_ring_srv_arb_en(csr, i, 0); } EXPORT_SYMBOL_GPL(adf_exit_arb); + +int adf_disable_arb_thd(struct adf_accel_dev *accel_dev, u32 ae, u32 thr) +{ + void __iomem *csr = accel_dev->transport->banks[0].csr_addr; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + const u32 *thd_2_arb_cfg; + struct arb_info info; + u32 ae_thr_map; + + if (ADF_AE_STRAND0_THREAD == thr || ADF_AE_STRAND1_THREAD == thr) + thr = ADF_AE_ADMIN_THREAD; + + hw_data->get_arb_info(&info); + thd_2_arb_cfg = hw_data->get_arb_mapping(accel_dev); + if (!thd_2_arb_cfg) + return -EFAULT; + + /* Disable scheduling for this particular AE and thread */ + ae_thr_map = *(thd_2_arb_cfg + ae); + ae_thr_map &= ~(GENMASK(3, 0) << (thr * BIT(2))); + + WRITE_CSR_ARB_WT2SAM(csr, info.arb_offset, info.wt2sam_offset, ae, + ae_thr_map); + return 0; +} --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_init.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_init.c @@ -433,6 +433,18 @@ return 0; } +void adf_error_notifier(struct adf_accel_dev *accel_dev) +{ + struct service_hndl *service; + + list_for_each_entry(service, &service_table, list) { + if (service->event_hld(accel_dev, ADF_EVENT_FATAL_ERROR)) + dev_err(&GET_DEV(accel_dev), + "Failed to send error event to %s.\n", + service->name); + } +} + static int adf_dev_shutdown_cache_cfg(struct adf_accel_dev *accel_dev) { char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_isr.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_isr.c @@ -139,8 +139,13 @@ if (ras_ops->handle_interrupt && ras_ops->handle_interrupt(accel_dev, &reset_required)) { - if (reset_required) + if (reset_required) { dev_err(&GET_DEV(accel_dev), "Fatal error, reset required\n"); + if (adf_notify_fatal_error(accel_dev)) + dev_err(&GET_DEV(accel_dev), + "Failed to notify fatal error\n"); + } + return true; } --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_msg.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_msg.h @@ -99,6 +99,8 @@ ADF_PF2VF_MSGTYPE_RESTARTING = 0x01, ADF_PF2VF_MSGTYPE_VERSION_RESP = 0x02, ADF_PF2VF_MSGTYPE_BLKMSG_RESP = 0x03, + ADF_PF2VF_MSGTYPE_FATAL_ERROR = 0x04, + ADF_PF2VF_MSGTYPE_RESTARTED = 0x05, /* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */ ADF_PF2VF_MSGTYPE_RP_RESET_RESP = 0x10, }; @@ -112,6 +114,7 @@ ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ = 0x07, ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ = 0x08, ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ = 0x09, + ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE = 0x0a, /* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */ ADF_VF2PF_MSGTYPE_RP_RESET = 0x10, }; @@ -124,8 +127,10 @@ ADF_PFVF_COMPAT_FAST_ACK = 0x03, /* Ring to service mapping support for non-standard mappings */ ADF_PFVF_COMPAT_RING_TO_SVC_MAP = 0x04, + /* Fallback compat */ + ADF_PFVF_COMPAT_FALLBACK = 0x05, /* Reference to the latest version */ - ADF_PFVF_COMPAT_THIS_VERSION = 0x04, + ADF_PFVF_COMPAT_THIS_VERSION = 0x05, }; /* PF->VF Version Response */ --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.c @@ -1,21 +1,83 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2015 - 2021 Intel Corporation */ +#include #include #include "adf_accel_devices.h" #include "adf_pfvf_msg.h" #include "adf_pfvf_pf_msg.h" #include "adf_pfvf_pf_proto.h" +#define ADF_PF_WAIT_RESTARTING_COMPLETE_DELAY 100 +#define ADF_VF_SHUTDOWN_RETRY 100 + void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev) { struct adf_accel_vf_info *vf; struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTING }; int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev)); + dev_dbg(&GET_DEV(accel_dev), "pf2vf notify restarting\n"); for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) { - if (vf->init && adf_send_pf2vf_msg(accel_dev, i, msg)) + vf->restarting = false; + if (!vf->init) + continue; + if (adf_send_pf2vf_msg(accel_dev, i, msg)) dev_err(&GET_DEV(accel_dev), "Failed to send restarting msg to VF%d\n", i); + else if (vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK) + vf->restarting = true; + } +} + +void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev) +{ + int num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev)); + int i, retries = ADF_VF_SHUTDOWN_RETRY; + struct adf_accel_vf_info *vf; + bool vf_running; + + dev_dbg(&GET_DEV(accel_dev), "pf2vf wait for restarting complete\n"); + do { + vf_running = false; + for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) + if (vf->restarting) + vf_running = true; + if (!vf_running) + break; + msleep(ADF_PF_WAIT_RESTARTING_COMPLETE_DELAY); + } while (--retries); + + if (vf_running) + dev_warn(&GET_DEV(accel_dev), "Some VFs are still running\n"); +} + +void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTED }; + int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev)); + struct adf_accel_vf_info *vf; + + dev_dbg(&GET_DEV(accel_dev), "pf2vf notify restarted\n"); + for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) { + if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK && + adf_send_pf2vf_msg(accel_dev, i, msg)) + dev_err(&GET_DEV(accel_dev), + "Failed to send restarted msg to VF%d\n", i); + } +} + +void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_FATAL_ERROR }; + int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev)); + struct adf_accel_vf_info *vf; + + dev_dbg(&GET_DEV(accel_dev), "pf2vf notify fatal error\n"); + for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) { + if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK && + adf_send_pf2vf_msg(accel_dev, i, msg)) + dev_err(&GET_DEV(accel_dev), + "Failed to send fatal error msg to VF%d\n", i); } } --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.h @@ -5,7 +5,28 @@ #include "adf_accel_devices.h" +#if defined(CONFIG_PCI_IOV) void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); +void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev); +void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev); +void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev); +#else +static inline void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev) +{ +} + +static inline void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev) +{ +} + +static inline void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev) +{ +} + +static inline void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev) +{ +} +#endif typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev, u8 *buffer, u8 compat); --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_proto.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_proto.c @@ -291,6 +291,14 @@ vf_info->init = false; } break; + case ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE: + { + dev_dbg(&GET_DEV(accel_dev), + "Restarting Complete received from VF%d\n", vf_nr); + vf_info->restarting = false; + vf_info->init = false; + } + break; case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ: case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ: case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ: --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_proto.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_proto.c @@ -308,6 +308,12 @@ adf_pf2vf_handle_pf_restarting(accel_dev); return false; + case ADF_PF2VF_MSGTYPE_RESTARTED: + dev_dbg(&GET_DEV(accel_dev), "Restarted message received from PF\n"); + return true; + case ADF_PF2VF_MSGTYPE_FATAL_ERROR: + dev_err(&GET_DEV(accel_dev), "Fatal error received from PF\n"); + return true; case ADF_PF2VF_MSGTYPE_VERSION_RESP: case ADF_PF2VF_MSGTYPE_BLKMSG_RESP: case ADF_PF2VF_MSGTYPE_RP_RESET_RESP: --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_rl.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_rl.c @@ -788,6 +788,24 @@ sla_type_arr[node_id] = NULL; } +static void free_all_sla(struct adf_accel_dev *accel_dev) +{ + struct adf_rl *rl_data = accel_dev->rate_limiting; + int sla_id; + + mutex_lock(&rl_data->rl_lock); + + for (sla_id = 0; sla_id < RL_NODES_CNT_MAX; sla_id++) { + if (!rl_data->sla[sla_id]) + continue; + + kfree(rl_data->sla[sla_id]); + rl_data->sla[sla_id] = NULL; + } + + mutex_unlock(&rl_data->rl_lock); +} + /** * add_update_sla() - handles the creation and the update of an SLA * @accel_dev: pointer to acceleration device structure @@ -1107,7 +1125,7 @@ } if ((fw_caps & RL_CAPABILITY_MASK) != RL_CAPABILITY_VALUE) { - dev_info(&GET_DEV(accel_dev), "not supported\n"); + dev_info(&GET_DEV(accel_dev), "feature not supported by FW\n"); ret = -EOPNOTSUPP; goto ret_free; } @@ -1155,7 +1173,7 @@ return; adf_sysfs_rl_rm(accel_dev); - adf_rl_remove_sla_all(accel_dev, true); + free_all_sla(accel_dev); } void adf_rl_exit(struct adf_accel_dev *accel_dev) --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_sriov.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_sriov.c @@ -60,7 +60,6 @@ /* This ptr will be populated when VFs will be created */ vf_info->accel_dev = accel_dev; vf_info->vf_nr = i; - vf_info->vf_compat_ver = 0; mutex_init(&vf_info->pf2vf_lock); ratelimit_state_init(&vf_info->vf2pf_ratelimit, @@ -84,6 +83,32 @@ return pci_enable_sriov(pdev, totalvfs); } +void adf_reenable_sriov(struct adf_accel_dev *accel_dev) +{ + struct pci_dev *pdev = accel_to_pci_dev(accel_dev); + char cfg[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; + unsigned long val = 0; + + if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, + ADF_SRIOV_ENABLED, cfg)) + return; + + if (!accel_dev->pf.vf_info) + return; + + if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_CY, + &val, ADF_DEC)) + return; + + if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_DC, + &val, ADF_DEC)) + return; + + set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status); + dev_dbg(&pdev->dev, "Re-enabling SRIOV\n"); + adf_enable_sriov(accel_dev); +} + /** * adf_disable_sriov() - Disable SRIOV for the device * @accel_dev: Pointer to accel device. @@ -103,6 +128,7 @@ return; adf_pf2vf_notify_restarting(accel_dev); + adf_pf2vf_wait_for_restarting_complete(accel_dev); pci_disable_sriov(accel_to_pci_dev(accel_dev)); /* Disable VF to PF interrupts */ @@ -115,8 +141,10 @@ for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++) mutex_destroy(&vf->pf2vf_lock); - kfree(accel_dev->pf.vf_info); - accel_dev->pf.vf_info = NULL; + if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status)) { + kfree(accel_dev->pf.vf_info); + accel_dev->pf.vf_info = NULL; + } } EXPORT_SYMBOL_GPL(adf_disable_sriov); @@ -194,6 +222,10 @@ if (ret) return ret; + val = 1; + adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC, ADF_SRIOV_ENABLED, + &val, ADF_DEC); + return numvfs; } EXPORT_SYMBOL_GPL(adf_sriov_configure); --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_sysfs.c @@ -204,6 +204,42 @@ } static DEVICE_ATTR_RW(pm_idle_enabled); +static ssize_t auto_reset_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + char *auto_reset; + struct adf_accel_dev *accel_dev; + + accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); + if (!accel_dev) + return -EINVAL; + + auto_reset = accel_dev->autoreset_on_error ? "on" : "off"; + + return sysfs_emit(buf, "%s\n", auto_reset); +} + +static ssize_t auto_reset_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct adf_accel_dev *accel_dev; + bool enabled = false; + int ret; + + ret = kstrtobool(buf, &enabled); + if (ret) + return ret; + + accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); + if (!accel_dev) + return -EINVAL; + + accel_dev->autoreset_on_error = enabled; + + return count; +} +static DEVICE_ATTR_RW(auto_reset); + static DEVICE_ATTR_RW(state); static DEVICE_ATTR_RW(cfg_services); @@ -291,6 +327,7 @@ &dev_attr_pm_idle_enabled.attr, &dev_attr_rp2srv.attr, &dev_attr_num_rps.attr, + &dev_attr_auto_reset.attr, NULL, }; --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_telemetry.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_telemetry.c @@ -41,6 +41,20 @@ return 0; } +static int validate_tl_slice_counters(struct icp_qat_fw_init_admin_slice_cnt *slice_count, + u8 max_slices_per_type) +{ + u8 *sl_counter = (u8 *)slice_count; + int i; + + for (i = 0; i < ADF_TL_SL_CNT_COUNT; i++) { + if (sl_counter[i] > max_slices_per_type) + return -EINVAL; + } + + return 0; +} + static int adf_tl_alloc_mem(struct adf_accel_dev *accel_dev) { struct adf_tl_hw_data *tl_data = &GET_TL_DATA(accel_dev); @@ -214,6 +228,13 @@ return ret; } + ret = validate_tl_slice_counters(&telemetry->slice_cnt, tl_data->max_sl_cnt); + if (ret) { + dev_err(dev, "invalid value returned by FW\n"); + adf_send_admin_tl_stop(accel_dev); + return ret; + } + telemetry->hbuffs = state; atomic_set(&telemetry->state, state); --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_telemetry.h +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/adf_telemetry.h @@ -40,6 +40,7 @@ u8 num_dev_counters; u8 num_rp_counters; u8 max_rp; + u8 max_sl_cnt; }; struct adf_telemetry { --- linux-xilinx-6.8.0.orig/drivers/crypto/intel/qat/qat_common/qat_comp_algs.c +++ linux-xilinx-6.8.0/drivers/crypto/intel/qat/qat_common/qat_comp_algs.c @@ -13,15 +13,6 @@ #include "qat_compression.h" #include "qat_algs_send.h" -#define QAT_RFC_1950_HDR_SIZE 2 -#define QAT_RFC_1950_FOOTER_SIZE 4 -#define QAT_RFC_1950_CM_DEFLATE 8 -#define QAT_RFC_1950_CM_DEFLATE_CINFO_32K 7 -#define QAT_RFC_1950_CM_MASK 0x0f -#define QAT_RFC_1950_CM_OFFSET 4 -#define QAT_RFC_1950_DICT_MASK 0x20 -#define QAT_RFC_1950_COMP_HDR 0x785e - static DEFINE_MUTEX(algs_lock); static unsigned int active_devs; --- linux-xilinx-6.8.0.orig/drivers/crypto/marvell/octeontx2/cn10k_cpt.c +++ linux-xilinx-6.8.0/drivers/crypto/marvell/octeontx2/cn10k_cpt.c @@ -138,6 +138,10 @@ return -ENOMEM; cptr_dma = dma_map_single(&pdev->dev, hctx, CN10K_CPT_HW_CTX_SIZE, DMA_BIDIRECTIONAL); + if (dma_mapping_error(&pdev->dev, cptr_dma)) { + kfree(hctx); + return -ENOMEM; + } cn10k_cpt_hw_ctx_set(hctx, 1); er_ctx->hw_ctx = hctx; --- linux-xilinx-6.8.0.orig/drivers/crypto/starfive/jh7110-rsa.c +++ linux-xilinx-6.8.0/drivers/crypto/starfive/jh7110-rsa.c @@ -273,7 +273,6 @@ err_rsa_crypt: writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET); - kfree(rctx->rsa_data); return ret; } --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/Makefile +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/Makefile @@ -1,3 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only +$(obj)/xilinx_ecdsasig.asn1.o: $(obj)/xilinx_ecdsasig.asn1.c $(obj)/xilinx_ecdsasig.asn1.h +xilinx-ecds-y += xilinx_ecdsasig.asn1.o +xilinx-ecds-y += xilinx-ecdsa.o +obj-$(CONFIG_CRYPTO_DEV_XILINX_ECDSA) += xilinx-ecds.o obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += zynqmp-aes-gcm.o obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_SHA3) += zynqmp-sha.o +obj-$(CONFIG_CRYPTO_DEV_XILINX_RSA) += zynqmp-rsa.o +obj-$(CONFIG_CRYPTO_DEV_XILINX_RSA_AKCIPHER) += xilinx-rsa.o --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/xilinx-ecdsa.c +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/xilinx-ecdsa.c @@ -0,0 +1,508 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD Versal ECDSA Driver. + * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xilinx_ecdsasig.asn1.h" + +/* PLM supports 32-bit addresses only */ +#define VERSAL_DMA_BIT_MASK 32U + +/* PLM can process HASH and signature in multiples of 8 bytes */ +#define ECDSA_P521_CURVE_ALIGN_BYTES 2U +/* Includes size for x and y coordinate. */ +#define ECDSA_MAX_KEY_SIZE (ECC_MAX_BYTES << 1) + +struct xilinx_sign_gen_params { + u64 hash_addr; + u64 privkey_addr; + u64 eprivkey_addr; + u32 curve_type; + u32 size; +}; + +struct xilinx_sign_verify_params { + u64 hash_addr; + u64 pubkey_addr; + u64 sign_addr; + u32 curve_type; + u32 size; +}; + +enum xilinx_crv_typ { + XSECURE_ECC_NIST_P384 = 4, + XSECURE_ECC_NIST_P521 = 5, +}; + +enum xilinx_crv_class { + XSECURE_ECDSA_PRIME = 0, + XSECURE_ECDSA_BINARY = 1, +}; + +struct xilinx_ecdsa_drv_ctx { + struct crypto_engine *engine; + struct akcipher_engine_alg alg; + struct device *dev; +}; + +enum xilinx_akcipher_op { + XILINX_ECDSA_DECRYPT = 0, + XILINX_ECDSA_ENCRYPT +}; + +struct xilinx_ecdsa_tfm_ctx { + dma_addr_t priv_key_addr, pub_key_addr; + struct crypto_akcipher *fbk_cipher; + const struct ecc_curve *curve; + unsigned int curve_id; + struct device *dev; + size_t key_size; + char *pub_kbuf; +}; + +struct xilinx_ecdsa_req_ctx { + enum xilinx_akcipher_op op; +}; + +static int xilinx_ecdsa_sign(struct akcipher_request *req) +{ + return 0; +} + +int xilinx_ecdsa_get_signature_r(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + struct ecdsa_signature_ctx *sig = context; + + return ecdsa_get_signature_rs(sig->r, hdrlen, tag, value, vlen, + sig->curve->g.ndigits); +} + +int xilinx_ecdsa_get_signature_s(void *context, size_t hdrlen, unsigned char tag, + const void *value, size_t vlen) +{ + struct ecdsa_signature_ctx *sig = context; + + return ecdsa_get_signature_rs(sig->s, hdrlen, tag, value, vlen, + sig->curve->g.ndigits); +} + +static int xilinx_ecdsa_verify(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct xilinx_ecdsa_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + size_t keylen = ctx->curve->g.ndigits * sizeof(u64); + dma_addr_t dma_addr, dma_addr1, dma_addr2; + struct xilinx_sign_verify_params *para; + char *hash_buf, *sign_buf; + u8 rawhash[ECC_MAX_BYTES]; + unsigned char *buffer; + ssize_t diff; + int ret; + struct ecdsa_signature_ctx sig_ctx = { + .curve = ctx->curve, + }; + + buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + sg_pcopy_to_buffer(req->src, + sg_nents_for_len(req->src, + req->src_len + req->dst_len), + buffer, req->src_len + req->dst_len, 0); + + ret = asn1_ber_decoder(&xilinx_ecdsasig_decoder, &sig_ctx, + buffer, req->src_len); + if (ret < 0) + goto error; + + /* + * If the hash is shorter then we will add leading zeros + * to fit to ndigits + */ + diff = keylen - req->dst_len; + if (diff >= 0) { + if (diff) + memset(rawhash, 0, diff); + memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len); + } else { + /* Given hash is longer, we take the left-most bytes */ + memcpy(&rawhash, buffer + req->src_len, keylen); + } + + para = dma_alloc_coherent(ctx->dev, + sizeof(struct xilinx_sign_verify_params), + &dma_addr, GFP_KERNEL); + if (!para) { + ret = -ENOMEM; + goto error; + } + + if (ctx->curve_id == XSECURE_ECC_NIST_P521) + keylen = ((ctx->curve->g.ndigits - 1) * sizeof(u64)) + ECDSA_P521_CURVE_ALIGN_BYTES; + /* ecc_swap_digits operates on u64 size data buffer */ + hash_buf = dma_alloc_coherent(ctx->dev, round_up(keylen, sizeof(u64)), + &dma_addr1, GFP_KERNEL); + if (!hash_buf) { + ret = -ENOMEM; + goto hash_fail; + } + + sign_buf = dma_alloc_coherent(ctx->dev, ctx->key_size, + &dma_addr2, GFP_KERNEL); + if (!sign_buf) { + ret = -ENOMEM; + goto sign_fail; + } + + para->pubkey_addr = ctx->pub_key_addr; + para->curve_type = ctx->curve_id; + para->sign_addr = dma_addr2; + para->hash_addr = dma_addr1; + para->size = keylen; + + memcpy(sign_buf, sig_ctx.r, keylen); + memcpy(sign_buf + keylen, sig_ctx.s, keylen); + + ecc_swap_digits((u64 *)rawhash, (u64 *)hash_buf, + ctx->curve->g.ndigits); + + ret = versal_pm_ecdsa_verify_sign(dma_addr); + + dma_free_coherent(ctx->dev, ctx->key_size, sign_buf, dma_addr2); + +sign_fail: + dma_free_coherent(ctx->dev, round_up(keylen, sizeof(u64)), hash_buf, dma_addr1); + +hash_fail: + dma_free_coherent(ctx->dev, sizeof(struct xilinx_sign_verify_params), + para, dma_addr); + +error: + kfree(buffer); + + return ret; +} + +static int xilinx_ecdsa_ctx_init(struct xilinx_ecdsa_tfm_ctx *ctx, + unsigned int curve_id) +{ + if (curve_id == ECC_CURVE_NIST_P384) + ctx->curve_id = XSECURE_ECC_NIST_P384; + else + ctx->curve_id = XSECURE_ECC_NIST_P521; + + ctx->curve = ecc_get_curve(curve_id); + if (!ctx->curve) + return -EINVAL; + + return 0; +} + +/* + * Set the public key given the raw uncompressed key data from an X509 + * certificate. The key data contain the concatenated X and Y coordinates of + * the public key. + */ +static int xilinx_ecdsa_set_pub_key(struct crypto_akcipher *tfm, + const void *key, unsigned int keylen) +{ + struct xilinx_ecdsa_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + unsigned int ndigits, key_size; + const unsigned char *d = key; + + if (keylen < 1 || ((keylen - 1) & 1) != 0) + return -EINVAL; + + /* The key should be in uncompressed format indicated by '4' */ + if (d[0] != 4) + return -EINVAL; + + keylen--; + ctx->key_size = keylen; + + key_size = keylen >> 1; + ndigits = DIV_ROUND_UP(key_size, sizeof(u64)); + if (ndigits != ctx->curve->g.ndigits) + return -EINVAL; + d++; + + ecc_digits_from_bytes(d, key_size, (u64 *)ctx->pub_kbuf, ndigits); + ecc_digits_from_bytes(&d[key_size], key_size, (u64 *)(ctx->pub_kbuf + key_size), ndigits); + + return versal_pm_ecdsa_validate_key(ctx->pub_key_addr, ctx->curve_id); +} + +static void xilinx_ecdsa_exit_tfm(struct crypto_akcipher *tfm) +{ + struct xilinx_ecdsa_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + + if (ctx->fbk_cipher) { + crypto_free_akcipher(ctx->fbk_cipher); + ctx->fbk_cipher = NULL; + } + + if (ctx->pub_kbuf) { + dma_free_coherent(ctx->dev, ECDSA_MAX_KEY_SIZE, + ctx->pub_kbuf, ctx->pub_key_addr); + } + + memzero_explicit(ctx, sizeof(struct xilinx_ecdsa_tfm_ctx)); +} + +static unsigned int xilinx_ecdsa_max_size(struct crypto_akcipher *tfm) +{ + const struct xilinx_ecdsa_tfm_ctx *ctx = akcipher_tfm_ctx(tfm); + + return DIV_ROUND_UP(ctx->curve->nbits, 8); +} + +static int xilinx_ecdsa_init_tfm(struct crypto_akcipher *tfm) +{ + struct xilinx_ecdsa_tfm_ctx *tfm_ctx = + (struct xilinx_ecdsa_tfm_ctx *)akcipher_tfm_ctx(tfm); + struct akcipher_alg *cipher_alg = crypto_akcipher_alg(tfm); + struct xilinx_ecdsa_drv_ctx *drv_ctx; + + drv_ctx = container_of(cipher_alg, struct xilinx_ecdsa_drv_ctx, alg.base); + tfm_ctx->dev = drv_ctx->dev; + + tfm_ctx->pub_kbuf = dma_alloc_coherent(tfm_ctx->dev, ECDSA_MAX_KEY_SIZE, + &tfm_ctx->pub_key_addr, GFP_KERNEL); + if (!tfm_ctx->pub_kbuf) + return -ENOMEM; + + tfm_ctx->fbk_cipher = crypto_alloc_akcipher(drv_ctx->alg.base.base.cra_name, + 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(tfm_ctx->fbk_cipher)) { + pr_err("%s() Error: failed to allocate fallback for %s\n", + __func__, drv_ctx->alg.base.base.cra_name); + dma_free_coherent(tfm_ctx->dev, ECDSA_MAX_KEY_SIZE, + tfm_ctx->pub_kbuf, tfm_ctx->pub_key_addr); + return PTR_ERR(tfm_ctx->fbk_cipher); + } + + akcipher_set_reqsize(tfm, max(sizeof(struct xilinx_ecdsa_req_ctx), + sizeof(struct akcipher_request) + + crypto_akcipher_reqsize(tfm_ctx->fbk_cipher))); + + if (strcmp(drv_ctx->alg.base.base.cra_name, "ecdsa-nist-p384") == 0) + return xilinx_ecdsa_ctx_init(tfm_ctx, ECC_CURVE_NIST_P384); + else + return xilinx_ecdsa_ctx_init(tfm_ctx, ECC_CURVE_NIST_P521); +} + +static int handle_ecdsa_req(struct crypto_engine *engine, void *req) +{ + struct akcipher_request *areq = container_of(req, + struct akcipher_request, + base); + struct crypto_akcipher *akcipher = crypto_akcipher_reqtfm(req); + const struct xilinx_ecdsa_tfm_ctx *tfm_ctx = akcipher_tfm_ctx(akcipher); + const struct xilinx_ecdsa_req_ctx *rq_ctx = akcipher_request_ctx(areq); + struct akcipher_request *subreq = akcipher_request_ctx(req); + int err; + + akcipher_request_set_tfm(subreq, tfm_ctx->fbk_cipher); + + akcipher_request_set_callback(subreq, areq->base.flags, NULL, NULL); + akcipher_request_set_crypt(subreq, areq->src, areq->dst, + areq->src_len, areq->dst_len); + + if (rq_ctx->op == XILINX_ECDSA_ENCRYPT) + err = crypto_akcipher_encrypt(subreq); + else if (rq_ctx->op == XILINX_ECDSA_DECRYPT) + err = crypto_akcipher_decrypt(subreq); + else + err = -EOPNOTSUPP; + + crypto_finalize_akcipher_request(engine, areq, err); + + return 0; +} + +static struct xilinx_ecdsa_drv_ctx versal_ecdsa_drv_ctx[] = { + { + .alg.base = { + .verify = xilinx_ecdsa_verify, + .set_pub_key = xilinx_ecdsa_set_pub_key, + .max_size = xilinx_ecdsa_max_size, + .init = xilinx_ecdsa_init_tfm, + .exit = xilinx_ecdsa_exit_tfm, + .sign = xilinx_ecdsa_sign, + .base = { + .cra_name = "ecdsa-nist-p384", + .cra_driver_name = "xilinx-ecdsa-nist-p384", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_NEED_FALLBACK, + .cra_module = THIS_MODULE, + .cra_ctxsize = sizeof(struct xilinx_ecdsa_tfm_ctx), + }, + }, + .alg.op = { + .do_one_request = handle_ecdsa_req, + } + }, + { + .alg.base = { + .verify = xilinx_ecdsa_verify, + .set_pub_key = xilinx_ecdsa_set_pub_key, + .max_size = xilinx_ecdsa_max_size, + .init = xilinx_ecdsa_init_tfm, + .exit = xilinx_ecdsa_exit_tfm, + .sign = xilinx_ecdsa_sign, + .base = { + .cra_name = "ecdsa-nist-p521", + .cra_driver_name = "xilinx-ecdsa-nist-p521", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_NEED_FALLBACK, + .cra_module = THIS_MODULE, + .cra_ctxsize = sizeof(struct xilinx_ecdsa_tfm_ctx), + }, + }, + .alg.op = { + .do_one_request = handle_ecdsa_req, + }, + } +}; + +static struct xlnx_feature ecdsa_feature_map[] = { + { + .family = VERSAL_FAMILY_CODE, + .subfamily = VERSAL_SUB_FAMILY_CODE, + .feature_id = XSECURE_API_ELLIPTIC_VALIDATE_KEY, + .data = &versal_ecdsa_drv_ctx, + }, + { /* sentinel */ } +}; + +static int xilinx_ecdsa_probe(struct platform_device *pdev) +{ + struct xilinx_ecdsa_drv_ctx *ecdsa_drv_ctx; + struct device *dev = &pdev->dev; + int ret, i; + + /* Verify the hardware is present */ + ecdsa_drv_ctx = xlnx_get_crypto_dev_data(ecdsa_feature_map); + if (IS_ERR(ecdsa_drv_ctx)) { + dev_err(dev, "ECDSA is not supported on the platform\n"); + return PTR_ERR(ecdsa_drv_ctx); + } + + ret = dma_set_mask_and_coherent(&pdev->dev, + DMA_BIT_MASK(VERSAL_DMA_BIT_MASK)); + if (ret < 0) { + dev_err(dev, "no usable DMA configuration"); + return ret; + } + + ecdsa_drv_ctx->engine = crypto_engine_alloc_init(dev, 1); + if (!ecdsa_drv_ctx->engine) { + dev_err(dev, "Cannot alloc ECDSA engine\n"); + return -ENOMEM; + } + + ret = crypto_engine_start(ecdsa_drv_ctx->engine); + if (ret) { + dev_err(dev, "Cannot start ECDSA engine\n"); + return ret; + } + + platform_set_drvdata(pdev, ecdsa_drv_ctx); + + for (i = 0; i < ARRAY_SIZE(versal_ecdsa_drv_ctx); i++) { + ecdsa_drv_ctx[i].dev = dev; + ret = crypto_engine_register_akcipher(&ecdsa_drv_ctx[i].alg); + + if (ret) { + dev_err(dev, "failed to register %s (%d)!\n", + ecdsa_drv_ctx[i].alg.base.base.cra_name, ret); + goto crypto_engine_cleanup; + } + } + + return 0; + +crypto_engine_cleanup: + for (--i; i >= 0; --i) + crypto_engine_unregister_akcipher(&ecdsa_drv_ctx[i].alg); + + crypto_engine_exit(ecdsa_drv_ctx->engine); + + return ret; +} + +static int xilinx_ecdsa_remove(struct platform_device *pdev) +{ + struct xilinx_ecdsa_drv_ctx *ecdsa_drv_ctx; + + ecdsa_drv_ctx = platform_get_drvdata(pdev); + + for (int i = 0; i < ARRAY_SIZE(versal_ecdsa_drv_ctx); i++) + crypto_engine_unregister_akcipher(&ecdsa_drv_ctx[i].alg); + + return 0; +} + +static struct platform_driver xilinx_ecdsa_driver = { + .probe = xilinx_ecdsa_probe, + .remove = xilinx_ecdsa_remove, + .driver = { + .name = "xilinx_ecdsa", + }, +}; + +static struct platform_device *platform_dev; + +static int __init ecdsa_driver_init(void) +{ + int ret; + + ret = platform_driver_register(&xilinx_ecdsa_driver); + if (ret) + return ret; + + platform_dev = platform_device_register_simple(xilinx_ecdsa_driver.driver.name, + 0, NULL, 0); + if (IS_ERR(platform_dev)) { + ret = PTR_ERR(platform_dev); + platform_driver_unregister(&xilinx_ecdsa_driver); + } + + return ret; +} + +static void __exit ecdsa_driver_exit(void) +{ + platform_device_unregister(platform_dev); + platform_driver_unregister(&xilinx_ecdsa_driver); +} + +module_init(ecdsa_driver_init) +module_exit(ecdsa_driver_exit); + +MODULE_DESCRIPTION("Versal ECDSA hw acceleration support."); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Harsha "); --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/xilinx-rsa.c +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/xilinx-rsa.c @@ -0,0 +1,597 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define XILINX_DMA_BIT_MASK 32U +#define XILINX_RSA_MAX_KEY_SIZE 1024 +#define XILINX_RSA_BLOCKSIZE 64 + +/* Key size in bytes */ +#define XSECURE_RSA_2048_KEY_SIZE (2048U / 8U) +#define XSECURE_RSA_3072_KEY_SIZE (3072U / 8U) +#define XSECURE_RSA_4096_KEY_SIZE (4096U / 8U) + +enum xilinx_akcipher_op { + XILINX_RSA_DECRYPT = 0, + XILINX_RSA_ENCRYPT, + XILINX_RSA_SIGN, + XILINX_RSA_VERIFY +}; + +struct versal_rsa_in_param { + u64 key_addr; + u64 data_addr; + u32 size; +}; + +struct xilinx_rsa_drv_ctx { + struct akcipher_engine_alg alg; + struct device *dev; + struct crypto_engine *engine; + int (*xilinx_rsa_xcrypt)(struct akcipher_request *req); +}; + +struct xilinx_rsa_tfm_ctx { + struct device *dev; + struct crypto_akcipher *fbk_cipher; + u8 *e_buf; + u8 *n_buf; + u8 *d_buf; + unsigned int key_len; /* in bits */ + unsigned int e_len; + unsigned int n_len; + unsigned int d_len; +}; + +struct xilinx_rsa_req_ctx { + enum xilinx_akcipher_op op; +}; + +static int zynqmp_rsa_xcrypt(struct akcipher_request *req) +{ + struct xilinx_rsa_req_ctx *rq_ctx = akcipher_request_ctx(req); + unsigned int len, offset, diff = req->dst_len - req->src_len; + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct xilinx_rsa_tfm_ctx *tctx = akcipher_tfm_ctx(tfm); + dma_addr_t dma_addr; + char *kbuf; + const char *buf; + size_t dma_size; + u8 padding = 0; + int ret; + + if (rq_ctx->op == XILINX_RSA_ENCRYPT) { + padding = tctx->e_len % 2; + buf = tctx->e_buf; + len = tctx->e_len; + } else { + buf = tctx->d_buf; + len = tctx->d_len; + } + + dma_size = req->dst_len + tctx->n_len + len + padding; + offset = dma_size - len; + + kbuf = dma_alloc_coherent(tctx->dev, dma_size, &dma_addr, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + scatterwalk_map_and_copy(kbuf + diff, req->src, 0, req->src_len, 0); + memcpy(kbuf + req->dst_len, tctx->n_buf, tctx->n_len); + + memcpy(kbuf + offset, buf, len); + + ret = zynqmp_pm_rsa(dma_addr, tctx->n_len, rq_ctx->op); + if (ret == 0) { + sg_copy_from_buffer(req->dst, sg_nents(req->dst), kbuf, + req->dst_len); + } + + dma_free_coherent(tctx->dev, dma_size, kbuf, dma_addr); + + return ret; +} + +static int versal_rsa_xcrypt(struct akcipher_request *req) +{ + const struct xilinx_rsa_req_ctx *rq_ctx = akcipher_request_ctx(req); + unsigned int len, offset, diff = req->dst_len - req->src_len; + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct xilinx_rsa_tfm_ctx *tctx = akcipher_tfm_ctx(tfm); + struct versal_rsa_in_param *para; + dma_addr_t dma_addr, dma_addr1; + char *kbuf; + const char *buf; + size_t dma_size; + u8 padding = 0; + int ret = 0; + + para = dma_alloc_coherent(tctx->dev, + sizeof(struct versal_rsa_in_param), + &dma_addr1, GFP_KERNEL); + if (!para) + return -ENOMEM; + + if (rq_ctx->op == XILINX_RSA_ENCRYPT) { + padding = tctx->e_len % 2; + buf = tctx->e_buf; + len = tctx->e_len; + } else { + buf = tctx->d_buf; + len = tctx->d_len; + } + + dma_size = req->dst_len + tctx->n_len + len + padding; + offset = dma_size - len; + + kbuf = dma_alloc_coherent(tctx->dev, dma_size, &dma_addr, GFP_KERNEL); + if (!kbuf) { + ret = -ENOMEM; + goto kbuf_fail; + } + + scatterwalk_map_and_copy(kbuf + diff, req->src, 0, req->src_len, 0); + + memcpy(kbuf + req->dst_len, tctx->n_buf, tctx->n_len); + + memcpy(kbuf + offset, buf, len); + + para->key_addr = (u64)(dma_addr + req->dst_len); + para->data_addr = (u64)dma_addr; + para->size = req->dst_len; + + if (rq_ctx->op == XILINX_RSA_ENCRYPT) + ret = versal_pm_rsa_encrypt(dma_addr1, dma_addr); + else + ret = versal_pm_rsa_decrypt(dma_addr1, dma_addr); + + if (ret == 0) { + sg_copy_from_buffer(req->dst, sg_nents(req->dst), kbuf, + req->dst_len); + } + dma_free_coherent(tctx->dev, dma_size, kbuf, dma_addr); + +kbuf_fail: + dma_free_coherent(tctx->dev, sizeof(struct versal_rsa_in_param), + para, dma_addr1); + + return ret; +} + +static int xilinx_rsa_decrypt(struct akcipher_request *req) +{ + struct xilinx_rsa_req_ctx *rctx = akcipher_request_ctx(req); + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + struct xilinx_rsa_drv_ctx *drv_ctx; + + rctx->op = XILINX_RSA_DECRYPT; + drv_ctx = container_of(alg, struct xilinx_rsa_drv_ctx, alg.base); + + return crypto_transfer_akcipher_request_to_engine(drv_ctx->engine, req); +} + +static int xilinx_rsa_encrypt(struct akcipher_request *req) +{ + struct xilinx_rsa_req_ctx *rctx = akcipher_request_ctx(req); + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct akcipher_alg *alg = crypto_akcipher_alg(tfm); + struct xilinx_rsa_drv_ctx *drv_ctx; + + rctx->op = XILINX_RSA_ENCRYPT; + drv_ctx = container_of(alg, struct xilinx_rsa_drv_ctx, alg.base); + + return crypto_transfer_akcipher_request_to_engine(drv_ctx->engine, req); +} + +static unsigned int xilinx_rsa_max_size(struct crypto_akcipher *tfm) +{ + const struct xilinx_rsa_tfm_ctx *tctx = akcipher_tfm_ctx(tfm); + + return tctx->n_len; +} + +static inline int xilinx_copy_and_save_keypart(u8 **kpbuf, unsigned int *kplen, + const u8 *buf, size_t sz) +{ + int nskip; + + for (nskip = 0; nskip < sz; nskip++) + if (buf[nskip]) + break; + + *kplen = sz - nskip; + *kpbuf = kmemdup(buf + nskip, *kplen, GFP_KERNEL); + if (!*kpbuf) + return -ENOMEM; + + return 0; +} + +static int xilinx_check_key_length(unsigned int len) +{ + if (len < 8 || len > 4096) + return -EINVAL; + return 0; +} + +static void xilinx_rsa_free_key_bufs(struct xilinx_rsa_tfm_ctx *ctx) +{ + /* Clean up old key data */ + kfree_sensitive(ctx->e_buf); + ctx->e_buf = NULL; + ctx->e_len = 0; + kfree_sensitive(ctx->n_buf); + ctx->n_buf = NULL; + ctx->n_len = 0; + kfree_sensitive(ctx->d_buf); + ctx->d_buf = NULL; + ctx->d_len = 0; +} + +static int xilinx_rsa_setkey(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen, bool private) +{ + struct xilinx_rsa_tfm_ctx *tctx = akcipher_tfm_ctx(tfm); + struct rsa_key raw_key; + int ret; + + if (private) + ret = rsa_parse_priv_key(&raw_key, key, keylen); + else + ret = rsa_parse_pub_key(&raw_key, key, keylen); + if (ret) + return ret; + + ret = xilinx_copy_and_save_keypart(&tctx->n_buf, &tctx->n_len, + raw_key.n, raw_key.n_sz); + if (ret) + return ret; + + /* convert to bits */ + tctx->key_len = tctx->n_len << 3; + if (xilinx_check_key_length(tctx->key_len)) { + ret = -EINVAL; + goto key_err; + } + + ret = xilinx_copy_and_save_keypart(&tctx->e_buf, &tctx->e_len, + raw_key.e, raw_key.e_sz); + if (ret) + goto key_err; + + if (private) { + ret = xilinx_copy_and_save_keypart(&tctx->d_buf, &tctx->d_len, + raw_key.d, raw_key.d_sz); + if (ret) + goto key_err; + } + + return 0; + +key_err: + xilinx_rsa_free_key_bufs(tctx); + return ret; +} + +static int xilinx_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct xilinx_rsa_tfm_ctx *tfm_ctx = akcipher_tfm_ctx(tfm); + int ret; + + tfm_ctx->fbk_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + tfm_ctx->fbk_cipher->base.crt_flags |= (tfm->base.crt_flags & + CRYPTO_TFM_REQ_MASK); + + ret = crypto_akcipher_set_priv_key(tfm_ctx->fbk_cipher, key, keylen); + if (ret) + return ret; + + return xilinx_rsa_setkey(tfm, key, keylen, true); +} + +static int xilinx_rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct xilinx_rsa_tfm_ctx *tfm_ctx = akcipher_tfm_ctx(tfm); + int ret; + + tfm_ctx->fbk_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + tfm_ctx->fbk_cipher->base.crt_flags |= (tfm->base.crt_flags & + CRYPTO_TFM_REQ_MASK); + + ret = crypto_akcipher_set_pub_key(tfm_ctx->fbk_cipher, key, keylen); + if (ret) + return ret; + + return xilinx_rsa_setkey(tfm, key, keylen, false); +} + +static int xilinx_fallback_check(const struct xilinx_rsa_tfm_ctx *tfm_ctx, + const struct akcipher_request *areq) +{ + /* Return 1 if fallback to crypto engine for performing requested operation */ + if (tfm_ctx->n_len != XSECURE_RSA_2048_KEY_SIZE && + tfm_ctx->n_len != XSECURE_RSA_3072_KEY_SIZE && + tfm_ctx->n_len != XSECURE_RSA_4096_KEY_SIZE) + return 1; + + if (areq->src_len > areq->dst_len) + return 1; + + return 0; +} + +static int handle_rsa_req(struct crypto_engine *engine, + void *req) +{ + struct akcipher_request *areq = container_of(req, + struct akcipher_request, + base); + struct crypto_akcipher *akcipher = crypto_akcipher_reqtfm(req); + struct akcipher_alg *cipher_alg = crypto_akcipher_alg(akcipher); + const struct xilinx_rsa_tfm_ctx *tfm_ctx = akcipher_tfm_ctx(akcipher); + const struct xilinx_rsa_req_ctx *rq_ctx = akcipher_request_ctx(areq); + struct akcipher_request *subreq = akcipher_request_ctx(req); + struct xilinx_rsa_drv_ctx *drv_ctx; + int need_fallback, err; + + drv_ctx = container_of(cipher_alg, struct xilinx_rsa_drv_ctx, alg.base); + + need_fallback = xilinx_fallback_check(tfm_ctx, areq); + if (need_fallback) { + akcipher_request_set_tfm(subreq, tfm_ctx->fbk_cipher); + + akcipher_request_set_callback(subreq, areq->base.flags, + NULL, NULL); + akcipher_request_set_crypt(subreq, areq->src, areq->dst, + areq->src_len, areq->dst_len); + + if (rq_ctx->op == XILINX_RSA_ENCRYPT) + err = crypto_akcipher_encrypt(subreq); + else if (rq_ctx->op == XILINX_RSA_DECRYPT) + err = crypto_akcipher_decrypt(subreq); + else + err = -EOPNOTSUPP; + } else { + err = drv_ctx->xilinx_rsa_xcrypt(areq); + } + + crypto_finalize_akcipher_request(engine, areq, err); + + return 0; +} + +static int xilinx_rsa_init(struct crypto_akcipher *tfm) +{ + struct xilinx_rsa_tfm_ctx *tfm_ctx = + (struct xilinx_rsa_tfm_ctx *)akcipher_tfm_ctx(tfm); + struct akcipher_alg *cipher_alg = crypto_akcipher_alg(tfm); + struct xilinx_rsa_drv_ctx *drv_ctx; + + drv_ctx = container_of(cipher_alg, struct xilinx_rsa_drv_ctx, alg.base); + tfm_ctx->dev = drv_ctx->dev; + tfm_ctx->fbk_cipher = crypto_alloc_akcipher(drv_ctx->alg.base.base.cra_name, + 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(tfm_ctx->fbk_cipher)) { + pr_err("%s() Error: failed to allocate fallback for %s\n", + __func__, drv_ctx->alg.base.base.cra_name); + return PTR_ERR(tfm_ctx->fbk_cipher); + } + + akcipher_set_reqsize(tfm, max(sizeof(struct xilinx_rsa_req_ctx), + sizeof(struct akcipher_request) + + crypto_akcipher_reqsize(tfm_ctx->fbk_cipher))); + + return 0; +} + +static void xilinx_rsa_exit(struct crypto_akcipher *tfm) +{ + struct xilinx_rsa_tfm_ctx *tfm_ctx = + (struct xilinx_rsa_tfm_ctx *)akcipher_tfm_ctx(tfm); + + xilinx_rsa_free_key_bufs(tfm_ctx); + + if (tfm_ctx->fbk_cipher) { + crypto_free_akcipher(tfm_ctx->fbk_cipher); + tfm_ctx->fbk_cipher = NULL; + } + memzero_explicit(tfm_ctx, sizeof(struct xilinx_rsa_tfm_ctx)); +} + +static struct xilinx_rsa_drv_ctx zynqmp_rsa_drv_ctx = { + .xilinx_rsa_xcrypt = zynqmp_rsa_xcrypt, + .alg.base = { + .init = xilinx_rsa_init, + .set_pub_key = xilinx_rsa_set_pub_key, + .set_priv_key = xilinx_rsa_set_priv_key, + .max_size = xilinx_rsa_max_size, + .decrypt = xilinx_rsa_decrypt, + .encrypt = xilinx_rsa_encrypt, + .sign = xilinx_rsa_decrypt, + .verify = xilinx_rsa_encrypt, + .exit = xilinx_rsa_exit, + .base = { + .cra_name = "rsa", + .cra_driver_name = "zynqmp-rsa", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = XILINX_RSA_BLOCKSIZE, + .cra_ctxsize = sizeof(struct xilinx_rsa_tfm_ctx), + .cra_alignmask = 15, + .cra_module = THIS_MODULE, + }, + }, + .alg.op = { + .do_one_request = handle_rsa_req, + }, +}; + +static struct xilinx_rsa_drv_ctx versal_rsa_drv_ctx = { + .xilinx_rsa_xcrypt = versal_rsa_xcrypt, + .alg.base = { + .init = xilinx_rsa_init, + .set_pub_key = xilinx_rsa_set_pub_key, + .set_priv_key = xilinx_rsa_set_priv_key, + .max_size = xilinx_rsa_max_size, + .decrypt = xilinx_rsa_decrypt, + .encrypt = xilinx_rsa_encrypt, + .sign = xilinx_rsa_decrypt, + .verify = xilinx_rsa_encrypt, + .exit = xilinx_rsa_exit, + .base = { + .cra_name = "rsa", + .cra_driver_name = "versal-rsa", + .cra_priority = 200, + .cra_flags = CRYPTO_ALG_TYPE_AKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = XILINX_RSA_BLOCKSIZE, + .cra_ctxsize = sizeof(struct xilinx_rsa_tfm_ctx), + .cra_alignmask = 15, + .cra_module = THIS_MODULE, + }, + }, + .alg.op = { + .do_one_request = handle_rsa_req, + }, +}; + +static struct xlnx_feature rsa_feature_map[] = { + { + .family = ZYNQMP_FAMILY_CODE, + .subfamily = ALL_SUB_FAMILY_CODE, + .feature_id = PM_SECURE_RSA, + .data = &zynqmp_rsa_drv_ctx, + }, + { + .family = VERSAL_FAMILY_CODE, + .subfamily = VERSAL_SUB_FAMILY_CODE, + .feature_id = XSECURE_API_RSA_PUBLIC_ENCRYPT, + .data = &versal_rsa_drv_ctx, + }, + { /* sentinel */ } +}; + +static int xilinx_rsa_probe(struct platform_device *pdev) +{ + struct xilinx_rsa_drv_ctx *rsa_drv_ctx; + struct device *dev = &pdev->dev; + int ret; + + /* Verify the hardware is present */ + rsa_drv_ctx = xlnx_get_crypto_dev_data(rsa_feature_map); + if (IS_ERR(rsa_drv_ctx)) { + dev_err(dev, "RSA is not supported on the platform\n"); + return PTR_ERR(rsa_drv_ctx); + } + + ret = dma_set_mask_and_coherent(dev, + DMA_BIT_MASK(XILINX_DMA_BIT_MASK)); + if (ret < 0) { + dev_err(dev, "no usable DMA configuration"); + return ret; + } + + rsa_drv_ctx->engine = crypto_engine_alloc_init(dev, 1); + if (!rsa_drv_ctx->engine) { + dev_err(dev, "Cannot alloc RSA engine\n"); + return -ENOMEM; + } + + ret = crypto_engine_start(rsa_drv_ctx->engine); + if (ret) { + dev_err(dev, "Cannot start RSA engine\n"); + goto out; + } + + rsa_drv_ctx->dev = dev; + platform_set_drvdata(pdev, rsa_drv_ctx); + + ret = crypto_engine_register_akcipher(&rsa_drv_ctx->alg); + if (ret < 0) { + dev_err(dev, "Failed to register akcipher alg.\n"); + goto out; + } + + return 0; + +out: + crypto_engine_exit(rsa_drv_ctx->engine); + + return ret; +} + +static int xilinx_rsa_remove(struct platform_device *pdev) +{ + struct xilinx_rsa_drv_ctx *rsa_drv_ctx; + + rsa_drv_ctx = platform_get_drvdata(pdev); + + crypto_engine_exit(rsa_drv_ctx->engine); + + crypto_engine_unregister_akcipher(&rsa_drv_ctx->alg); + + return 0; +} + +static struct platform_driver xilinx_rsa_driver = { + .probe = xilinx_rsa_probe, + .remove = xilinx_rsa_remove, + .driver = { + .name = "xilinx_rsa", + }, +}; + +static struct platform_device *platform_dev; + +static int __init xilinx_rsa_driver_init(void) +{ + int ret; + + ret = platform_driver_register(&xilinx_rsa_driver); + if (ret) + return ret; + + platform_dev = platform_device_register_simple(xilinx_rsa_driver.driver.name, + 0, NULL, 0); + if (IS_ERR(platform_dev)) { + ret = PTR_ERR(platform_dev); + platform_driver_unregister(&xilinx_rsa_driver); + } + + return ret; +} + +static void __exit xilinx_rsa_driver_exit(void) +{ + platform_device_unregister(platform_dev); + platform_driver_unregister(&xilinx_rsa_driver); +} + +module_init(xilinx_rsa_driver_init); +module_exit(xilinx_rsa_driver_exit); + +MODULE_DESCRIPTION("Xilinx RSA hw acceleration support."); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Harsha "); --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/xilinx_ecdsasig.asn1 +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/xilinx_ecdsasig.asn1 @@ -0,0 +1,4 @@ +ECDSASignature ::= SEQUENCE { + r INTEGER ({ xilinx_ecdsa_get_signature_r }), + s INTEGER ({ xilinx_ecdsa_get_signature_s }) +} --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/zynqmp-aes-gcm.c +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/zynqmp-aes-gcm.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* * Xilinx ZynqMP AES Driver. - * Copyright (c) 2020 Xilinx Inc. + * Copyright (C) 2020 - 2022 Xilinx Inc. + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. */ #include @@ -26,6 +27,8 @@ #define ZYNQMP_AES_BLK_SIZE 1U #define ZYNQMP_AES_MIN_INPUT_BLK_SIZE 4U #define ZYNQMP_AES_WORD_LEN 4U +#define VERSAL_AES_QWORD_LEN 16U +#define ZYNQMP_AES_DEVICE_LEY_LEN 1U #define ZYNQMP_AES_GCM_TAG_MISMATCH_ERR 0x01 #define ZYNQMP_AES_WRONG_KEY_SRC_ERR 0x13 @@ -42,12 +45,59 @@ ZYNQMP_AES_PUF_KEY }; -struct zynqmp_aead_drv_ctx { - union { - struct aead_engine_alg aead; - } alg; +enum versal_aead_keysrc { + VERSAL_AES_BBRAM_KEY = 0, + VERSAL_AES_BBRAM_RED_KEY, + VERSAL_AES_BH_KEY, + VERSAL_AES_BH_RED_KEY, + VERSAL_AES_EFUSE_KEY, + VERSAL_AES_EFUSE_RED_KEY, + VERSAL_AES_EFUSE_USER_KEY_0, + VERSAL_AES_EFUSE_USER_KEY_1, + VERSAL_AES_EFUSE_USER_RED_KEY_0, + VERSAL_AES_EFUSE_USER_RED_KEY_1, + VERSAL_AES_KUP_KEY, + VERSAL_AES_PUF_KEY, + VERSAL_AES_USER_KEY_0, + VERSAL_AES_USER_KEY_1, + VERSAL_AES_USER_KEY_2, + VERSAL_AES_USER_KEY_3, + VERSAL_AES_USER_KEY_4, + VERSAL_AES_USER_KEY_5, + VERSAL_AES_USER_KEY_6, + VERSAL_AES_USER_KEY_7, + VERSAL_AES_EXPANDED_KEYS, + VERSAL_AES_ALL_KEYS, +}; + +enum versal_aead_op { + VERSAL_AES_ENCRYPT = 0, + VERSAL_AES_DECRYPT +}; + +enum versal_aes_keysize { + AES_KEY_SIZE_128 = 0, + AES_KEY_SIZE_256 = 2, +}; + +struct zynqmp_aead_tfm_ctx { + struct device *dev; + u8 key[ZYNQMP_AES_KEY_SIZE]; + u8 *iv; + u32 keylen; + u32 authsize; + u8 keysrc; + struct crypto_aead *fbk_cipher; +}; + +struct xilinx_aead_drv_ctx { + struct aead_engine_alg aead; struct device *dev; struct crypto_engine *engine; + u8 keysrc; + int (*aes_aead_cipher)(struct aead_request *areq); + int (*fallback_check)(struct zynqmp_aead_tfm_ctx *ctx, + struct aead_request *areq); }; struct zynqmp_aead_hw_req { @@ -60,20 +110,23 @@ u64 keysrc; }; -struct zynqmp_aead_tfm_ctx { - struct device *dev; - u8 key[ZYNQMP_AES_KEY_SIZE]; - u8 *iv; - u32 keylen; - u32 authsize; - enum zynqmp_aead_keysrc keysrc; - struct crypto_aead *fbk_cipher; -}; - struct zynqmp_aead_req_ctx { enum zynqmp_aead_op op; }; +struct versal_init_ops { + u64 iv; + u32 op; + u32 keysrc; + u32 size; +}; + +struct versal_in_params { + u64 in_data_addr; + u32 size; + u32 is_last; +}; + static int zynqmp_aes_aead_cipher(struct aead_request *req) { struct crypto_aead *aead = crypto_aead_reqtfm(req); @@ -174,46 +227,210 @@ return err; } +static int versal_aes_aead_cipher(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead); + struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req); + dma_addr_t dma_addr_data, dma_addr_hw_req, dma_addr_in; + u32 total_len = req->assoclen + req->cryptlen; + u32 key_offset = total_len + GCM_AES_IV_SIZE; + struct device *dev = tfm_ctx->dev; + struct versal_init_ops *hwreq; + struct versal_in_params *in; + u32 gcm_offset, out_len; + size_t dma_size; + char *kbuf; + int ret; + + if (tfm_ctx->keylen != XSECURE_AES_KEY_SIZE_128 && + tfm_ctx->keylen != XSECURE_AES_KEY_SIZE_256) { + ret = -EINVAL; + goto err; + } + + dma_size = key_offset; + /* Allocate keylen for volatile user keys */ + if (tfm_ctx->keysrc >= VERSAL_AES_USER_KEY_0 && tfm_ctx->keysrc <= VERSAL_AES_USER_KEY_7) + dma_size += tfm_ctx->keylen; + + kbuf = dma_alloc_coherent(dev, dma_size, &dma_addr_data, GFP_KERNEL); + if (!kbuf) { + ret = -ENOMEM; + goto err; + } + + /* + * Allocated separate memory as separate structure for init ops + * Also to avoid big continuous memory allocation + */ + hwreq = dma_alloc_coherent(dev, sizeof(struct versal_init_ops), + &dma_addr_hw_req, GFP_KERNEL); + if (!hwreq) { + ret = -ENOMEM; + goto hwreq_fail; + } + + /* + * Allocated separate memory as separate structure for in params + * Also to avoid big continuous memory allocation + */ + in = dma_alloc_coherent(dev, sizeof(struct versal_in_params), + &dma_addr_in, GFP_KERNEL); + if (!in) { + ret = -ENOMEM; + goto in_fail; + } + + scatterwalk_map_and_copy(kbuf, req->src, 0, total_len, 0); + memcpy(kbuf + total_len, req->iv, GCM_AES_IV_SIZE); + hwreq->iv = dma_addr_data + total_len; + hwreq->keysrc = tfm_ctx->keysrc; + + if (rq_ctx->op == ZYNQMP_AES_ENCRYPT) { + hwreq->op = VERSAL_AES_ENCRYPT; + out_len = total_len + ZYNQMP_AES_AUTH_SIZE; + in->size = req->cryptlen; + } else { + hwreq->op = VERSAL_AES_DECRYPT; + out_len = total_len - ZYNQMP_AES_AUTH_SIZE; + in->size = req->cryptlen - ZYNQMP_AES_AUTH_SIZE; + } + + if (tfm_ctx->keylen == XSECURE_AES_KEY_SIZE_128) + hwreq->size = AES_KEY_SIZE_128; + else if (tfm_ctx->keylen == XSECURE_AES_KEY_SIZE_256) + hwreq->size = AES_KEY_SIZE_256; + + /* Request aes key write for volatile user keys */ + if (hwreq->keysrc >= VERSAL_AES_USER_KEY_0 && hwreq->keysrc <= VERSAL_AES_USER_KEY_7) { + memcpy(kbuf + key_offset, tfm_ctx->key, tfm_ctx->keylen); + ret = versal_pm_aes_key_write(hwreq->size, hwreq->keysrc, + dma_addr_data + key_offset); + if (ret) + goto key_fail; + } + + ret = versal_pm_aes_op_init(dma_addr_hw_req); + if (ret) + goto clearkey; + + if (req->assoclen > 0) { + /* Currently GMAC is OFF by default */ + ret = versal_pm_aes_update_aad(dma_addr_data, req->assoclen); + if (ret) + goto clearkey; + } + + in->in_data_addr = dma_addr_data + req->assoclen; + in->is_last = 1; + gcm_offset = req->assoclen + in->size; + + if (rq_ctx->op == ZYNQMP_AES_ENCRYPT) { + ret = versal_pm_aes_enc_update(dma_addr_in, + dma_addr_data + req->assoclen); + if (ret) + goto clearkey; + + ret = versal_pm_aes_enc_final(dma_addr_data + gcm_offset); + if (ret) + goto clearkey; + } else { + ret = versal_pm_aes_dec_update(dma_addr_in, + dma_addr_data + req->assoclen); + if (ret) + goto clearkey; + + ret = versal_pm_aes_dec_final(dma_addr_data + gcm_offset); + if (ret) { + ret = -EBADMSG; + goto clearkey; + } + } + + sg_copy_from_buffer(req->dst, sg_nents(req->dst), + kbuf, out_len); + +clearkey: + if (hwreq->keysrc >= VERSAL_AES_USER_KEY_0 && hwreq->keysrc <= VERSAL_AES_USER_KEY_7) + versal_pm_aes_key_zero(hwreq->keysrc); +key_fail: + dma_free_coherent(dev, sizeof(struct versal_in_params), in, dma_addr_in); +in_fail: + memzero_explicit(hwreq, sizeof(struct versal_init_ops)); + dma_free_coherent(dev, sizeof(struct versal_init_ops), hwreq, dma_addr_hw_req); +hwreq_fail: + memzero_explicit(kbuf, dma_size); + dma_free_coherent(dev, dma_size, kbuf, dma_addr_data); +err: + return ret; +} + static int zynqmp_fallback_check(struct zynqmp_aead_tfm_ctx *tfm_ctx, struct aead_request *req) { - int need_fallback = 0; struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req); - if (tfm_ctx->authsize != ZYNQMP_AES_AUTH_SIZE) - need_fallback = 1; + if ((tfm_ctx->keysrc == ZYNQMP_AES_KUP_KEY && + tfm_ctx->keylen != ZYNQMP_AES_KEY_SIZE) || + (tfm_ctx->keysrc == ZYNQMP_AES_DEV_KEY && + tfm_ctx->keylen != ZYNQMP_AES_DEVICE_LEY_LEN)) + return 1; - if (tfm_ctx->keysrc == ZYNQMP_AES_KUP_KEY && - tfm_ctx->keylen != ZYNQMP_AES_KEY_SIZE) { - need_fallback = 1; - } if (req->assoclen != 0 || - req->cryptlen < ZYNQMP_AES_MIN_INPUT_BLK_SIZE) { - need_fallback = 1; - } + req->cryptlen < ZYNQMP_AES_MIN_INPUT_BLK_SIZE) + return 1; + if ((req->cryptlen % ZYNQMP_AES_WORD_LEN) != 0) - need_fallback = 1; + return 1; if (rq_ctx->op == ZYNQMP_AES_DECRYPT && - req->cryptlen <= ZYNQMP_AES_AUTH_SIZE) { - need_fallback = 1; - } - return need_fallback; + req->cryptlen <= ZYNQMP_AES_AUTH_SIZE) + return 1; + + return 0; +} + +static int versal_fallback_check(struct zynqmp_aead_tfm_ctx *tfm_ctx, + struct aead_request *req) +{ + struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req); + + if (tfm_ctx->authsize != ZYNQMP_AES_AUTH_SIZE) + return 1; + + if (tfm_ctx->keylen != XSECURE_AES_KEY_SIZE_128 && + tfm_ctx->keylen != XSECURE_AES_KEY_SIZE_256) + return 1; + + if (req->cryptlen < ZYNQMP_AES_MIN_INPUT_BLK_SIZE || + req->cryptlen % ZYNQMP_AES_WORD_LEN || + req->assoclen % VERSAL_AES_QWORD_LEN) + return 1; + + if (rq_ctx->op == ZYNQMP_AES_DECRYPT && + req->cryptlen <= ZYNQMP_AES_AUTH_SIZE) + return 1; + + return 0; } -static int zynqmp_handle_aes_req(struct crypto_engine *engine, - void *req) +static int handle_aes_req(struct crypto_engine *engine, void *req) { struct aead_request *areq = container_of(req, struct aead_request, base); struct crypto_aead *aead = crypto_aead_reqtfm(req); struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead); + struct aead_alg *alg = crypto_aead_alg(aead); + struct xilinx_aead_drv_ctx *drv_ctx; + struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(areq); struct aead_request *subreq = aead_request_ctx(req); int need_fallback; int err; - need_fallback = zynqmp_fallback_check(tfm_ctx, areq); + drv_ctx = container_of(alg, struct xilinx_aead_drv_ctx, aead.base); + need_fallback = drv_ctx->fallback_check(tfm_ctx, areq); if (need_fallback) { aead_request_set_tfm(subreq, tfm_ctx->fbk_cipher); @@ -228,10 +445,13 @@ else err = crypto_aead_decrypt(subreq); } else { - err = zynqmp_aes_aead_cipher(areq); + err = drv_ctx->aes_aead_cipher(areq); } + local_bh_disable(); crypto_finalize_aead_request(engine, areq, err); + local_bh_enable(); + return 0; } @@ -248,10 +468,10 @@ if (keysrc == ZYNQMP_AES_KUP_KEY || keysrc == ZYNQMP_AES_DEV_KEY || keysrc == ZYNQMP_AES_PUF_KEY) { - tfm_ctx->keysrc = (enum zynqmp_aead_keysrc)keysrc; - } else { + tfm_ctx->keysrc = keysrc; tfm_ctx->keylen = keylen; } + return 0; } else { tfm_ctx->keylen = keylen; if (keylen == ZYNQMP_AES_KEY_SIZE) { @@ -267,6 +487,48 @@ return crypto_aead_setkey(tfm_ctx->fbk_cipher, key, keylen); } +static int versal_aes_aead_setkey(struct crypto_aead *aead, const u8 *key, + unsigned int keylen) +{ + struct crypto_tfm *tfm = crypto_aead_tfm(aead); + struct zynqmp_aead_tfm_ctx *tfm_ctx = + (struct zynqmp_aead_tfm_ctx *)crypto_tfm_ctx(tfm); + + if (keylen == ZYNQMP_KEY_SRC_SEL_KEY_LEN) { + unsigned char keysrc = VERSAL_AES_EFUSE_USER_KEY_0; + + keysrc = *key; + if ((keysrc >= VERSAL_AES_EFUSE_USER_KEY_0 && + keysrc <= VERSAL_AES_USER_KEY_7) && + keysrc != VERSAL_AES_KUP_KEY) { + tfm_ctx->keysrc = keysrc; + return 0; + } + return -EINVAL; + } else { + tfm_ctx->keylen = keylen; + if (keylen == XSECURE_AES_KEY_SIZE_256 || + keylen == XSECURE_AES_KEY_SIZE_128) { + if (tfm_ctx->keysrc >= VERSAL_AES_USER_KEY_0 && + tfm_ctx->keysrc <= VERSAL_AES_USER_KEY_7) { + memcpy(tfm_ctx->key, key, keylen); + } + } + + if (tfm_ctx->keysrc < VERSAL_AES_EFUSE_USER_KEY_0 || + tfm_ctx->keysrc > VERSAL_AES_USER_KEY_7 || + tfm_ctx->keysrc == VERSAL_AES_KUP_KEY) { + tfm_ctx->keysrc = VERSAL_AES_USER_KEY_0; + } + } + + tfm_ctx->fbk_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + tfm_ctx->fbk_cipher->base.crt_flags |= (aead->base.crt_flags & + CRYPTO_TFM_REQ_MASK); + + return crypto_aead_setkey(tfm_ctx->fbk_cipher, key, keylen); +} + static int zynqmp_aes_aead_setauthsize(struct crypto_aead *aead, unsigned int authsize) { @@ -280,48 +542,49 @@ static int zynqmp_aes_aead_encrypt(struct aead_request *req) { - struct zynqmp_aead_drv_ctx *drv_ctx; + struct xilinx_aead_drv_ctx *drv_ctx; struct crypto_aead *aead = crypto_aead_reqtfm(req); struct aead_alg *alg = crypto_aead_alg(aead); struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req); rq_ctx->op = ZYNQMP_AES_ENCRYPT; - drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, alg.aead.base); + drv_ctx = container_of(alg, struct xilinx_aead_drv_ctx, aead.base); return crypto_transfer_aead_request_to_engine(drv_ctx->engine, req); } static int zynqmp_aes_aead_decrypt(struct aead_request *req) { - struct zynqmp_aead_drv_ctx *drv_ctx; + struct xilinx_aead_drv_ctx *drv_ctx; struct crypto_aead *aead = crypto_aead_reqtfm(req); struct aead_alg *alg = crypto_aead_alg(aead); struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req); rq_ctx->op = ZYNQMP_AES_DECRYPT; - drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, alg.aead.base); + drv_ctx = container_of(alg, struct xilinx_aead_drv_ctx, aead.base); return crypto_transfer_aead_request_to_engine(drv_ctx->engine, req); } -static int zynqmp_aes_aead_init(struct crypto_aead *aead) +static int aes_aead_init(struct crypto_aead *aead) { struct crypto_tfm *tfm = crypto_aead_tfm(aead); struct zynqmp_aead_tfm_ctx *tfm_ctx = (struct zynqmp_aead_tfm_ctx *)crypto_tfm_ctx(tfm); - struct zynqmp_aead_drv_ctx *drv_ctx; + struct xilinx_aead_drv_ctx *drv_ctx; struct aead_alg *alg = crypto_aead_alg(aead); - drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, alg.aead.base); + drv_ctx = container_of(alg, struct xilinx_aead_drv_ctx, aead.base); tfm_ctx->dev = drv_ctx->dev; + tfm_ctx->keysrc = drv_ctx->keysrc; - tfm_ctx->fbk_cipher = crypto_alloc_aead(drv_ctx->alg.aead.base.base.cra_name, + tfm_ctx->fbk_cipher = crypto_alloc_aead(drv_ctx->aead.base.base.cra_name, 0, CRYPTO_ALG_NEED_FALLBACK); if (IS_ERR(tfm_ctx->fbk_cipher)) { pr_err("%s() Error: failed to allocate fallback for %s\n", - __func__, drv_ctx->alg.aead.base.base.cra_name); + __func__, drv_ctx->aead.base.base.cra_name); return PTR_ERR(tfm_ctx->fbk_cipher); } @@ -345,20 +608,55 @@ memzero_explicit(tfm_ctx, sizeof(struct zynqmp_aead_tfm_ctx)); } -static struct zynqmp_aead_drv_ctx aes_drv_ctx = { - .alg.aead.base = { +static struct xilinx_aead_drv_ctx zynqmp_aes_drv_ctx = { + .fallback_check = zynqmp_fallback_check, + .aes_aead_cipher = zynqmp_aes_aead_cipher, + .keysrc = ZYNQMP_AES_KUP_KEY, + .aead.base = { .setkey = zynqmp_aes_aead_setkey, .setauthsize = zynqmp_aes_aead_setauthsize, .encrypt = zynqmp_aes_aead_encrypt, .decrypt = zynqmp_aes_aead_decrypt, - .init = zynqmp_aes_aead_init, + .init = aes_aead_init, + .exit = zynqmp_aes_aead_exit, + .ivsize = GCM_AES_IV_SIZE, + .maxauthsize = ZYNQMP_AES_AUTH_SIZE, + .base = { + .cra_name = "gcm(aes)", + .cra_driver_name = "zynqmp-aes-gcm", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = ZYNQMP_AES_BLK_SIZE, + .cra_ctxsize = sizeof(struct zynqmp_aead_tfm_ctx), + .cra_module = THIS_MODULE, + } + }, + .aead.op = { + .do_one_request = handle_aes_req, + }, +}; + +static struct xilinx_aead_drv_ctx versal_aes_drv_ctx = { + .fallback_check = versal_fallback_check, + .aes_aead_cipher = versal_aes_aead_cipher, + .keysrc = VERSAL_AES_USER_KEY_0, + .aead.base = { + .setkey = versal_aes_aead_setkey, + .setauthsize = zynqmp_aes_aead_setauthsize, + .encrypt = zynqmp_aes_aead_encrypt, + .decrypt = zynqmp_aes_aead_decrypt, + .init = aes_aead_init, .exit = zynqmp_aes_aead_exit, .ivsize = GCM_AES_IV_SIZE, .maxauthsize = ZYNQMP_AES_AUTH_SIZE, .base = { .cra_name = "gcm(aes)", - .cra_driver_name = "xilinx-zynqmp-aes-gcm", - .cra_priority = 200, + .cra_driver_name = "versal-aes-gcm", + .cra_priority = 300, .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | @@ -369,78 +667,126 @@ .cra_module = THIS_MODULE, } }, - .alg.aead.op = { - .do_one_request = zynqmp_handle_aes_req, + .aead.op = { + .do_one_request = handle_aes_req, }, }; +static struct xlnx_feature aes_feature_map[] = { + { + .family = ZYNQMP_FAMILY_CODE, + .subfamily = ALL_SUB_FAMILY_CODE, + .feature_id = PM_SECURE_AES, + .data = &zynqmp_aes_drv_ctx, + }, + { + .family = VERSAL_FAMILY_CODE, + .subfamily = VERSAL_SUB_FAMILY_CODE, + .feature_id = XSECURE_API_AES_OP_INIT, + .data = &versal_aes_drv_ctx, + }, + { /* sentinel */ } +}; + static int zynqmp_aes_aead_probe(struct platform_device *pdev) { + struct xilinx_aead_drv_ctx *aes_drv_ctx; struct device *dev = &pdev->dev; int err; + /* Verify the hardware is present */ + aes_drv_ctx = xlnx_get_crypto_dev_data(aes_feature_map); + if (IS_ERR(aes_drv_ctx)) { + dev_err(dev, "AES is not supported on the platform\n"); + return PTR_ERR(aes_drv_ctx); + } + /* ZynqMP AES driver supports only one instance */ - if (!aes_drv_ctx.dev) - aes_drv_ctx.dev = dev; + if (!aes_drv_ctx->dev) + aes_drv_ctx->dev = dev; else return -ENODEV; + platform_set_drvdata(pdev, aes_drv_ctx); + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(ZYNQMP_DMA_BIT_MASK)); if (err < 0) { dev_err(dev, "No usable DMA configuration\n"); return err; } - aes_drv_ctx.engine = crypto_engine_alloc_init(dev, 1); - if (!aes_drv_ctx.engine) { + aes_drv_ctx->engine = crypto_engine_alloc_init(dev, 1); + if (!aes_drv_ctx->engine) { dev_err(dev, "Cannot alloc AES engine\n"); err = -ENOMEM; goto err_engine; } - err = crypto_engine_start(aes_drv_ctx.engine); + err = crypto_engine_start(aes_drv_ctx->engine); if (err) { dev_err(dev, "Cannot start AES engine\n"); goto err_engine; } - err = crypto_engine_register_aead(&aes_drv_ctx.alg.aead); + err = crypto_engine_register_aead(&aes_drv_ctx->aead); if (err < 0) { dev_err(dev, "Failed to register AEAD alg.\n"); - goto err_aead; + goto err_engine; } return 0; -err_aead: - crypto_engine_unregister_aead(&aes_drv_ctx.alg.aead); - err_engine: - if (aes_drv_ctx.engine) - crypto_engine_exit(aes_drv_ctx.engine); + if (aes_drv_ctx->engine) + crypto_engine_exit(aes_drv_ctx->engine); return err; } static void zynqmp_aes_aead_remove(struct platform_device *pdev) { - crypto_engine_exit(aes_drv_ctx.engine); - crypto_engine_unregister_aead(&aes_drv_ctx.alg.aead); -} + struct xilinx_aead_drv_ctx *aes_drv_ctx; -static const struct of_device_id zynqmp_aes_dt_ids[] = { - { .compatible = "xlnx,zynqmp-aes" }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, zynqmp_aes_dt_ids); + aes_drv_ctx = platform_get_drvdata(pdev); + + crypto_engine_exit(aes_drv_ctx->engine); + crypto_engine_unregister_aead(&aes_drv_ctx->aead); +} static struct platform_driver zynqmp_aes_driver = { .probe = zynqmp_aes_aead_probe, .remove_new = zynqmp_aes_aead_remove, .driver = { .name = "zynqmp-aes", - .of_match_table = zynqmp_aes_dt_ids, }, }; -module_platform_driver(zynqmp_aes_driver); +static struct platform_device *platform_dev; + +static int __init aes_driver_init(void) +{ + int ret; + + ret = platform_driver_register(&zynqmp_aes_driver); + if (ret) + return ret; + + platform_dev = platform_device_register_simple(zynqmp_aes_driver.driver.name, + 0, NULL, 0); + if (IS_ERR(platform_dev)) { + ret = PTR_ERR(platform_dev); + platform_driver_unregister(&zynqmp_aes_driver); + } + + return ret; +} + +static void __exit aes_driver_exit(void) +{ + platform_device_unregister(platform_dev); + platform_driver_unregister(&zynqmp_aes_driver); +} + +device_initcall(aes_driver_init); +module_exit(aes_driver_exit); + MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/zynqmp-rsa.c +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/zynqmp-rsa.c @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 - 2022 Xilinx, Inc. + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ZYNQMP_RSA_QUEUE_LENGTH 1 +#define ZYNQMP_RSA_MAX_KEY_SIZE 1024 +#define ZYNQMP_RSA_BLOCKSIZE 64 + +/* Key size in bytes */ +#define XSECURE_RSA_2048_KEY_SIZE (2048U / 8U) +#define XSECURE_RSA_3072_KEY_SIZE (3072U / 8U) +#define XSECURE_RSA_4096_KEY_SIZE (4096U / 8U) + +static struct zynqmp_rsa_dev *rsa_dd; + +struct zynqmp_rsa_op { + struct zynqmp_rsa_dev *dd; + void *src; + void *dst; + int len; + u8 key[ZYNQMP_RSA_MAX_KEY_SIZE]; + u8 *iv; + u32 keylen; +}; + +struct zynqmp_rsa_dev { + struct list_head list; + struct device *dev; + /* the lock protects queue and dev list*/ + spinlock_t lock; + struct crypto_queue queue; + struct skcipher_alg *alg; +}; + +struct zynqmp_rsa_drv { + struct list_head dev_list; + /* the lock protects queue and dev list*/ + spinlock_t lock; +}; + +static struct zynqmp_rsa_drv zynqmp_rsa = { + .dev_list = LIST_HEAD_INIT(zynqmp_rsa.dev_list), + .lock = __SPIN_LOCK_UNLOCKED(zynqmp_rsa.lock), +}; + +static struct zynqmp_rsa_dev *zynqmp_rsa_find_dev(struct zynqmp_rsa_op *ctx) +{ + struct zynqmp_rsa_dev *dd = rsa_dd; + + spin_lock_bh(&zynqmp_rsa.lock); + if (!ctx->dd) + ctx->dd = dd; + else + dd = ctx->dd; + spin_unlock_bh(&zynqmp_rsa.lock); + + return dd; +} + +static int zynqmp_setkey_blk(struct crypto_skcipher *tfm, const u8 *key, + unsigned int len) +{ + struct zynqmp_rsa_op *op = crypto_skcipher_ctx(tfm); + + op->keylen = len; + memcpy(op->key, key, len); + return 0; +} + +static int zynqmp_rsa_xcrypt(struct skcipher_request *req, unsigned int flags) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct zynqmp_rsa_op *op = crypto_skcipher_ctx(tfm); + struct zynqmp_rsa_dev *dd = zynqmp_rsa_find_dev(op); + int err, datasize, src_data = 0, dst_data = 0; + struct skcipher_walk walk = {0}; + unsigned int nbytes; + char *kbuf; + size_t dma_size; + dma_addr_t dma_addr; + + nbytes = req->cryptlen; + if (nbytes != XSECURE_RSA_2048_KEY_SIZE && + nbytes != XSECURE_RSA_3072_KEY_SIZE && + nbytes != XSECURE_RSA_4096_KEY_SIZE) { + return -EOPNOTSUPP; + } + + dma_size = nbytes + op->keylen; + kbuf = dma_alloc_coherent(dd->dev, dma_size, &dma_addr, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + err = skcipher_walk_virt(&walk, req, false); + if (err) + goto out; + + while ((datasize = walk.nbytes)) { + op->src = walk.src.virt.addr; + memcpy(kbuf + src_data, op->src, datasize); + src_data = src_data + datasize; + err = skcipher_walk_done(&walk, 0); + if (err) + goto out; + } + memcpy(kbuf + nbytes, op->key, op->keylen); + + zynqmp_pm_rsa(dma_addr, nbytes, flags); + + err = skcipher_walk_virt(&walk, req, false); + if (err) + goto out; + + while ((datasize = walk.nbytes)) { + memcpy(walk.dst.virt.addr, kbuf + dst_data, datasize); + dst_data = dst_data + datasize; + err = skcipher_walk_done(&walk, 0); + if (err) + goto out; + } + +out: + dma_free_coherent(dd->dev, dma_size, kbuf, dma_addr); + return err; +} + +static int zynqmp_rsa_decrypt(struct skcipher_request *req) +{ + return zynqmp_rsa_xcrypt(req, 0); +} + +static int zynqmp_rsa_encrypt(struct skcipher_request *req) +{ + return zynqmp_rsa_xcrypt(req, 1); +} + +static struct skcipher_alg zynqmp_alg = { + .base.cra_name = "xilinx-zynqmp-rsa", + .base.cra_driver_name = "zynqmp-rsa", + .base.cra_priority = 400, + .base.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY, + .base.cra_blocksize = ZYNQMP_RSA_BLOCKSIZE, + .base.cra_ctxsize = sizeof(struct zynqmp_rsa_op), + .base.cra_alignmask = 15, + .base.cra_module = THIS_MODULE, + .min_keysize = 0, + .max_keysize = ZYNQMP_RSA_MAX_KEY_SIZE, + .setkey = zynqmp_setkey_blk, + .encrypt = zynqmp_rsa_encrypt, + .decrypt = zynqmp_rsa_decrypt, + .ivsize = 1, +}; + +static struct xlnx_feature rsa_feature_map[] = { + { + .family = ZYNQMP_FAMILY_CODE, + .subfamily = ALL_SUB_FAMILY_CODE, + .feature_id = PM_SECURE_RSA, + .data = &zynqmp_alg, + }, + { /* sentinel */ } +}; + +static int zynqmp_rsa_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret; + + rsa_dd = devm_kzalloc(&pdev->dev, sizeof(*rsa_dd), GFP_KERNEL); + if (!rsa_dd) + return -ENOMEM; + + rsa_dd->alg = xlnx_get_crypto_dev_data(rsa_feature_map); + if (IS_ERR(rsa_dd->alg)) { + dev_err(dev, "RSA is not supported on the platform\n"); + return PTR_ERR(rsa_dd->alg); + } + + dev_warn(dev, "This driver is deprecated. Please migrate to xilinx-rsa driver\n"); + rsa_dd->dev = dev; + platform_set_drvdata(pdev, rsa_dd); + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret < 0) + dev_err(dev, "no usable DMA configuration"); + + INIT_LIST_HEAD(&rsa_dd->list); + spin_lock_init(&rsa_dd->lock); + crypto_init_queue(&rsa_dd->queue, ZYNQMP_RSA_QUEUE_LENGTH); + spin_lock(&zynqmp_rsa.lock); + list_add_tail(&rsa_dd->list, &zynqmp_rsa.dev_list); + spin_unlock(&zynqmp_rsa.lock); + + ret = crypto_register_skcipher(rsa_dd->alg); + if (ret) + goto err_algs; + + return 0; + +err_algs: + spin_lock(&zynqmp_rsa.lock); + list_del(&rsa_dd->list); + spin_unlock(&zynqmp_rsa.lock); + dev_err(dev, "initialization failed.\n"); + return ret; +} + +static int zynqmp_rsa_remove(struct platform_device *pdev) +{ + struct zynqmp_rsa_dev *drv_ctx; + + drv_ctx = platform_get_drvdata(pdev); + + crypto_unregister_skcipher(drv_ctx->alg); + + return 0; +} + +static struct platform_driver xilinx_rsa_driver = { + .probe = zynqmp_rsa_probe, + .remove = zynqmp_rsa_remove, + .driver = { + .name = "zynqmp_rsa", + }, +}; + +static struct platform_device *platform_dev; + +static int __init rsa_driver_init(void) +{ + int ret; + + ret = platform_driver_register(&xilinx_rsa_driver); + if (ret) + return ret; + + platform_dev = platform_device_register_simple(xilinx_rsa_driver.driver.name, + 0, NULL, 0); + if (IS_ERR(platform_dev)) { + ret = PTR_ERR(platform_dev); + platform_driver_unregister(&xilinx_rsa_driver); + } + + return ret; +} + +static void __exit rsa_driver_exit(void) +{ + platform_device_unregister(platform_dev); + platform_driver_unregister(&xilinx_rsa_driver); +} + +device_initcall(rsa_driver_init); +module_exit(rsa_driver_exit); + +MODULE_DESCRIPTION("ZynqMP RSA hw acceleration support."); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nava kishore Manne "); --- linux-xilinx-6.8.0.orig/drivers/crypto/xilinx/zynqmp-sha.c +++ linux-xilinx-6.8.0/drivers/crypto/xilinx/zynqmp-sha.c @@ -2,8 +2,10 @@ /* * Xilinx ZynqMP SHA Driver. * Copyright (c) 2022 Xilinx Inc. + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. */ #include +#include #include #include #include @@ -17,7 +19,13 @@ #include #include +#define CONTINUE_PACKET BIT(31) +#define FIRST_PACKET BIT(30) +#define FINAL_PACKET 0 +#define RESET 0 + #define ZYNQMP_DMA_BIT_MASK 32U +#define VERSAL_DMA_BIT_MASK 64U #define ZYNQMP_DMA_ALLOC_FIXED_SIZE 0x1000U enum zynqmp_sha_op { @@ -26,198 +34,359 @@ ZYNQMP_SHA3_FINAL = 4, }; -struct zynqmp_sha_drv_ctx { - struct shash_alg sha3_384; +struct xilinx_sha_drv_ctx { + struct ahash_engine_alg sha3_384; + struct crypto_engine *engine; struct device *dev; + u8 dma_addr_size; }; struct zynqmp_sha_tfm_ctx { struct device *dev; - struct crypto_shash *fbk_tfm; + struct crypto_ahash *fbk_tfm; }; struct zynqmp_sha_desc_ctx { - struct shash_desc fbk_req; + struct ahash_request fallback_req; }; static dma_addr_t update_dma_addr, final_dma_addr; static char *ubuf, *fbuf; -static int zynqmp_sha_init_tfm(struct crypto_shash *hash) +static int zynqmp_sha_init_tfm(struct crypto_tfm *tfm) { - const char *fallback_driver_name = crypto_shash_alg_name(hash); - struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash); - struct shash_alg *alg = crypto_shash_alg(hash); - struct crypto_shash *fallback_tfm; - struct zynqmp_sha_drv_ctx *drv_ctx; + const char *fallback_driver_name = crypto_tfm_alg_name(tfm); + struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); + struct hash_alg_common *alg = crypto_hash_alg_common(__crypto_ahash_cast(tfm)); + struct crypto_ahash *fallback_tfm; + struct xilinx_sha_drv_ctx *drv_ctx; - drv_ctx = container_of(alg, struct zynqmp_sha_drv_ctx, sha3_384); + drv_ctx = container_of(alg, struct xilinx_sha_drv_ctx, sha3_384.base.halg); tfm_ctx->dev = drv_ctx->dev; /* Allocate a fallback and abort if it failed. */ - fallback_tfm = crypto_alloc_shash(fallback_driver_name, 0, + fallback_tfm = crypto_alloc_ahash(fallback_driver_name, CRYPTO_ALG_TYPE_SHASH, CRYPTO_ALG_NEED_FALLBACK); if (IS_ERR(fallback_tfm)) return PTR_ERR(fallback_tfm); tfm_ctx->fbk_tfm = fallback_tfm; - hash->descsize += crypto_shash_descsize(tfm_ctx->fbk_tfm); + crypto_ahash_set_statesize(__crypto_ahash_cast(tfm), + crypto_ahash_statesize(fallback_tfm)); + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + crypto_ahash_reqsize(tfm_ctx->fbk_tfm) + + sizeof(struct zynqmp_sha_desc_ctx)); return 0; } -static void zynqmp_sha_exit_tfm(struct crypto_shash *hash) +static void zynqmp_sha_exit_tfm(struct crypto_tfm *tfm) { - struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash); + struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); if (tfm_ctx->fbk_tfm) { - crypto_free_shash(tfm_ctx->fbk_tfm); + crypto_free_ahash(tfm_ctx->fbk_tfm); tfm_ctx->fbk_tfm = NULL; } memzero_explicit(tfm_ctx, sizeof(struct zynqmp_sha_tfm_ctx)); } -static int zynqmp_sha_init(struct shash_desc *desc) +static int zynqmp_sha_init(struct ahash_request *req) +{ + struct zynqmp_sha_desc_ctx *dctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct zynqmp_sha_tfm_ctx *tctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&dctx->fallback_req, tctx->fbk_tfm); + dctx->fallback_req.base.flags = req->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + return crypto_ahash_init(&dctx->fallback_req); +} + +static int zynqmp_sha_update(struct ahash_request *req) { - struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc); - struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + struct zynqmp_sha_desc_ctx *dctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct zynqmp_sha_tfm_ctx *tctx = crypto_ahash_ctx(tfm); - dctx->fbk_req.tfm = tctx->fbk_tfm; - return crypto_shash_init(&dctx->fbk_req); + ahash_request_set_tfm(&dctx->fallback_req, tctx->fbk_tfm); + dctx->fallback_req.base.flags = req->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + dctx->fallback_req.nbytes = req->nbytes; + dctx->fallback_req.src = req->src; + return crypto_ahash_update(&dctx->fallback_req); } -static int zynqmp_sha_update(struct shash_desc *desc, const u8 *data, unsigned int length) +static int zynqmp_sha_final(struct ahash_request *req) { - struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc); + struct zynqmp_sha_desc_ctx *dctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct zynqmp_sha_tfm_ctx *tctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&dctx->fallback_req, tctx->fbk_tfm); + dctx->fallback_req.base.flags = req->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + dctx->fallback_req.result = req->result; - return crypto_shash_update(&dctx->fbk_req, data, length); + return crypto_ahash_final(&dctx->fallback_req); } -static int zynqmp_sha_final(struct shash_desc *desc, u8 *out) +static int zynqmp_sha_finup(struct ahash_request *req) { - struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc); + struct zynqmp_sha_desc_ctx *dctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct zynqmp_sha_tfm_ctx *tctx = crypto_ahash_ctx(tfm); - return crypto_shash_final(&dctx->fbk_req, out); + ahash_request_set_tfm(&dctx->fallback_req, tctx->fbk_tfm); + dctx->fallback_req.base.flags = req->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + + dctx->fallback_req.nbytes = req->nbytes; + dctx->fallback_req.src = req->src; + dctx->fallback_req.result = req->result; + + return crypto_ahash_finup(&dctx->fallback_req); } -static int zynqmp_sha_finup(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out) +static int zynqmp_sha_import(struct ahash_request *req, const void *in) { - struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc); + struct zynqmp_sha_desc_ctx *dctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct zynqmp_sha_tfm_ctx *tctx = crypto_ahash_ctx(tfm); + + ahash_request_set_tfm(&dctx->fallback_req, tctx->fbk_tfm); + dctx->fallback_req.base.flags = req->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; - return crypto_shash_finup(&dctx->fbk_req, data, length, out); + return crypto_ahash_import(&dctx->fallback_req, in); } -static int zynqmp_sha_import(struct shash_desc *desc, const void *in) +static int zynqmp_sha_export(struct ahash_request *req, void *out) { - struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc); - struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + struct zynqmp_sha_desc_ctx *dctx = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct zynqmp_sha_tfm_ctx *tctx = crypto_ahash_ctx(tfm); - dctx->fbk_req.tfm = tctx->fbk_tfm; - return crypto_shash_import(&dctx->fbk_req, in); + ahash_request_set_tfm(&dctx->fallback_req, tctx->fbk_tfm); + dctx->fallback_req.base.flags = req->base.flags & + CRYPTO_TFM_REQ_MAY_SLEEP; + + return crypto_ahash_export(&dctx->fallback_req, out); } -static int zynqmp_sha_export(struct shash_desc *desc, void *out) +static int sha_digest(struct ahash_request *req) { - struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc); + struct crypto_tfm *tfm = crypto_ahash_tfm(crypto_ahash_reqtfm(req)); + struct hash_alg_common *alg = crypto_hash_alg_common(__crypto_ahash_cast(tfm)); + struct xilinx_sha_drv_ctx *drv_ctx; + + drv_ctx = container_of(alg, struct xilinx_sha_drv_ctx, sha3_384.base.halg); - return crypto_shash_export(&dctx->fbk_req, out); + return crypto_transfer_hash_request_to_engine(drv_ctx->engine, req); } -static int zynqmp_sha_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) +static int zynqmp_sha_digest(struct ahash_request *req) { - unsigned int remaining_len = len; + unsigned int processed = 0; + unsigned int remaining_len; int update_size; int ret; + remaining_len = req->nbytes; ret = zynqmp_pm_sha_hash(0, 0, ZYNQMP_SHA3_INIT); if (ret) return ret; - while (remaining_len != 0) { - memzero_explicit(ubuf, ZYNQMP_DMA_ALLOC_FIXED_SIZE); - if (remaining_len >= ZYNQMP_DMA_ALLOC_FIXED_SIZE) { + while (remaining_len) { + if (remaining_len >= ZYNQMP_DMA_ALLOC_FIXED_SIZE) update_size = ZYNQMP_DMA_ALLOC_FIXED_SIZE; - remaining_len -= ZYNQMP_DMA_ALLOC_FIXED_SIZE; - } else { + else update_size = remaining_len; - remaining_len = 0; - } - memcpy(ubuf, data, update_size); + sg_pcopy_to_buffer(req->src, sg_nents(req->src), ubuf, update_size, processed); flush_icache_range((unsigned long)ubuf, (unsigned long)ubuf + update_size); ret = zynqmp_pm_sha_hash(update_dma_addr, update_size, ZYNQMP_SHA3_UPDATE); if (ret) return ret; - data += update_size; + remaining_len -= update_size; + processed += update_size; } ret = zynqmp_pm_sha_hash(final_dma_addr, SHA3_384_DIGEST_SIZE, ZYNQMP_SHA3_FINAL); - memcpy(out, fbuf, SHA3_384_DIGEST_SIZE); + memcpy(req->result, fbuf, SHA3_384_DIGEST_SIZE); memzero_explicit(fbuf, SHA3_384_DIGEST_SIZE); return ret; } -static struct zynqmp_sha_drv_ctx sha3_drv_ctx = { - .sha3_384 = { +static int versal_sha_digest(struct ahash_request *req) +{ + int update_size, ret, flag = FIRST_PACKET; + unsigned int processed = 0; + unsigned int remaining_len; + + remaining_len = req->nbytes; + while (remaining_len) { + if (remaining_len >= ZYNQMP_DMA_ALLOC_FIXED_SIZE) + update_size = ZYNQMP_DMA_ALLOC_FIXED_SIZE; + else + update_size = remaining_len; + + sg_pcopy_to_buffer(req->src, sg_nents(req->src), ubuf, update_size, processed); + flush_icache_range((unsigned long)ubuf, + (unsigned long)ubuf + update_size); + + flag |= CONTINUE_PACKET; + ret = versal_pm_sha_hash(update_dma_addr, 0, + update_size | flag); + if (ret) + return ret; + + remaining_len -= update_size; + processed += update_size; + flag = RESET; + } + + flag |= FINAL_PACKET; + ret = versal_pm_sha_hash(0, final_dma_addr, flag); + if (ret) + return ret; + + memcpy(req->result, fbuf, SHA3_384_DIGEST_SIZE); + memzero_explicit(fbuf, SHA3_384_DIGEST_SIZE); + + return 0; +} + +static int handle_zynqmp_sha_engine_req(struct crypto_engine *engine, void *req) +{ + int err; + + err = zynqmp_sha_digest(req); + local_bh_disable(); + crypto_finalize_hash_request(engine, req, err); + local_bh_enable(); + + return 0; +} + +static int handle_versal_sha_engine_req(struct crypto_engine *engine, void *req) +{ + int err; + + err = versal_sha_digest(req); + local_bh_disable(); + crypto_finalize_hash_request(engine, req, err); + local_bh_enable(); + + return 0; +} + +static struct xilinx_sha_drv_ctx zynqmp_sha3_drv_ctx = { + .sha3_384.base = { .init = zynqmp_sha_init, .update = zynqmp_sha_update, .final = zynqmp_sha_final, .finup = zynqmp_sha_finup, - .digest = zynqmp_sha_digest, + .digest = sha_digest, .export = zynqmp_sha_export, .import = zynqmp_sha_import, - .init_tfm = zynqmp_sha_init_tfm, - .exit_tfm = zynqmp_sha_exit_tfm, - .descsize = sizeof(struct zynqmp_sha_desc_ctx), - .statesize = sizeof(struct sha3_state), - .digestsize = SHA3_384_DIGEST_SIZE, - .base = { - .cra_name = "sha3-384", - .cra_driver_name = "zynqmp-sha3-384", - .cra_priority = 300, - .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | - CRYPTO_ALG_ALLOCATES_MEMORY | - CRYPTO_ALG_NEED_FALLBACK, - .cra_blocksize = SHA3_384_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct zynqmp_sha_tfm_ctx), - .cra_module = THIS_MODULE, + .halg = { + .digestsize = SHA3_384_DIGEST_SIZE, + .statesize = sizeof(struct sha3_state), + .base.cra_init = zynqmp_sha_init_tfm, + .base.cra_exit = zynqmp_sha_exit_tfm, + .base.cra_name = "sha3-384", + .base.cra_driver_name = "zynqmp-sha3-384", + .base.cra_priority = 300, + .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = SHA3_384_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct zynqmp_sha_tfm_ctx), + .base.cra_module = THIS_MODULE, } - } + }, + .sha3_384.op = { + .do_one_request = handle_zynqmp_sha_engine_req, + }, + .dma_addr_size = ZYNQMP_DMA_BIT_MASK, +}; + +static struct xilinx_sha_drv_ctx versal_sha3_drv_ctx = { + .sha3_384.base = { + .init = zynqmp_sha_init, + .update = zynqmp_sha_update, + .final = zynqmp_sha_final, + .finup = zynqmp_sha_finup, + .digest = sha_digest, + .export = zynqmp_sha_export, + .import = zynqmp_sha_import, + .halg = { + .base.cra_init = zynqmp_sha_init_tfm, + .base.cra_exit = zynqmp_sha_exit_tfm, + .base.cra_name = "sha3-384", + .base.cra_driver_name = "versal-sha3-384", + .base.cra_priority = 300, + .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = SHA3_384_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct zynqmp_sha_tfm_ctx), + .base.cra_module = THIS_MODULE, + .statesize = sizeof(struct sha3_state), + .digestsize = SHA3_384_DIGEST_SIZE, + } + }, + .sha3_384.op = { + .do_one_request = handle_versal_sha_engine_req, + }, + .dma_addr_size = VERSAL_DMA_BIT_MASK, +}; + +static struct xlnx_feature sha_feature_map[] = { + { + .family = ZYNQMP_FAMILY_CODE, + .subfamily = ALL_SUB_FAMILY_CODE, + .feature_id = PM_SECURE_SHA, + .data = &zynqmp_sha3_drv_ctx, + }, + { + .family = VERSAL_FAMILY_CODE, + .subfamily = VERSAL_SUB_FAMILY_CODE, + .feature_id = XSECURE_API_SHA3_UPDATE, + .data = &versal_sha3_drv_ctx, + }, + { /* sentinel */ } }; static int zynqmp_sha_probe(struct platform_device *pdev) { + struct xilinx_sha_drv_ctx *sha3_drv_ctx; struct device *dev = &pdev->dev; int err; - u32 v; /* Verify the hardware is present */ - err = zynqmp_pm_get_api_version(&v); - if (err) - return err; - - - err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(ZYNQMP_DMA_BIT_MASK)); - if (err < 0) { - dev_err(dev, "No usable DMA configuration\n"); - return err; + sha3_drv_ctx = xlnx_get_crypto_dev_data(sha_feature_map); + if (IS_ERR(sha3_drv_ctx)) { + dev_err(dev, "SHA is not supported on the platform\n"); + return PTR_ERR(sha3_drv_ctx); } - err = crypto_register_shash(&sha3_drv_ctx.sha3_384); + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(sha3_drv_ctx->dma_addr_size)); if (err < 0) { - dev_err(dev, "Failed to register shash alg.\n"); + dev_err(dev, "No usable DMA configuration\n"); return err; } - sha3_drv_ctx.dev = dev; - platform_set_drvdata(pdev, &sha3_drv_ctx); + sha3_drv_ctx->dev = dev; + platform_set_drvdata(pdev, sha3_drv_ctx); ubuf = dma_alloc_coherent(dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, &update_dma_addr, GFP_KERNEL); if (!ubuf) { err = -ENOMEM; - goto err_shash; + return err; } fbuf = dma_alloc_coherent(dev, SHA3_384_DIGEST_SIZE, &final_dma_addr, GFP_KERNEL); @@ -226,24 +395,47 @@ goto err_mem; } + sha3_drv_ctx->engine = crypto_engine_alloc_init(dev, 1); + if (!sha3_drv_ctx->engine) { + dev_err(dev, "Cannot alloc Crypto engine\n"); + err = -ENOMEM; + goto err_engine; + } + + err = crypto_engine_start(sha3_drv_ctx->engine); + if (err) { + dev_err(dev, "Cannot start AES engine\n"); + goto err_start; + } + + err = crypto_engine_register_ahash(&sha3_drv_ctx->sha3_384); + if (err < 0) { + dev_err(dev, "Failed to register sha3 alg.\n"); + goto err_start; + } + return 0; -err_mem: - dma_free_coherent(sha3_drv_ctx.dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr); +err_start: + crypto_engine_exit(sha3_drv_ctx->engine); +err_engine: + dma_free_coherent(dev, SHA3_384_DIGEST_SIZE, fbuf, final_dma_addr); -err_shash: - crypto_unregister_shash(&sha3_drv_ctx.sha3_384); +err_mem: + dma_free_coherent(dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr); return err; } static void zynqmp_sha_remove(struct platform_device *pdev) { - sha3_drv_ctx.dev = platform_get_drvdata(pdev); + struct xilinx_sha_drv_ctx *sha3_drv_ctx; - dma_free_coherent(sha3_drv_ctx.dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr); - dma_free_coherent(sha3_drv_ctx.dev, SHA3_384_DIGEST_SIZE, fbuf, final_dma_addr); - crypto_unregister_shash(&sha3_drv_ctx.sha3_384); + sha3_drv_ctx = platform_get_drvdata(pdev); + crypto_engine_unregister_ahash(&sha3_drv_ctx->sha3_384); + crypto_engine_exit(sha3_drv_ctx->engine); + dma_free_coherent(sha3_drv_ctx->dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr); + dma_free_coherent(sha3_drv_ctx->dev, SHA3_384_DIGEST_SIZE, fbuf, final_dma_addr); } static struct platform_driver zynqmp_sha_driver = { @@ -254,7 +446,35 @@ }, }; -module_platform_driver(zynqmp_sha_driver); +static struct platform_device *platform_dev; + +static int __init sha_driver_init(void) +{ + int ret; + + ret = platform_driver_register(&zynqmp_sha_driver); + if (ret) + return ret; + + platform_dev = platform_device_register_simple(zynqmp_sha_driver.driver.name, + 0, NULL, 0); + if (IS_ERR(platform_dev)) { + ret = PTR_ERR(platform_dev); + platform_driver_unregister(&zynqmp_sha_driver); + } + + return ret; +} + +static void __exit sha_driver_exit(void) +{ + platform_device_unregister(platform_dev); + platform_driver_unregister(&zynqmp_sha_driver); +} + +device_initcall(sha_driver_init); +module_exit(sha_driver_exit); + MODULE_DESCRIPTION("ZynqMP SHA3 hardware acceleration support."); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Harsha "); --- linux-xilinx-6.8.0.orig/drivers/cxl/acpi.c +++ linux-xilinx-6.8.0/drivers/cxl/acpi.c @@ -530,13 +530,15 @@ if (kstrtou32(acpi_device_uid(hb), 0, &uid)) return -EINVAL; - rc = acpi_get_genport_coordinates(uid, &dport->hb_coord); + rc = acpi_get_genport_coordinates(uid, dport->hb_coord); if (rc < 0) return rc; /* Adjust back to picoseconds from nanoseconds */ - dport->hb_coord.read_latency *= 1000; - dport->hb_coord.write_latency *= 1000; + for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) { + dport->hb_coord[i].read_latency *= 1000; + dport->hb_coord[i].write_latency *= 1000; + } return 0; } --- linux-xilinx-6.8.0.orig/drivers/cxl/core/cdat.c +++ linux-xilinx-6.8.0/drivers/cxl/core/cdat.c @@ -162,15 +162,22 @@ static int cxl_port_perf_data_calculate(struct cxl_port *port, struct xarray *dsmas_xa) { - struct access_coordinate c; + struct access_coordinate ep_c; + struct access_coordinate coord[ACCESS_COORDINATE_MAX]; struct dsmas_entry *dent; int valid_entries = 0; unsigned long index; int rc; - rc = cxl_endpoint_get_perf_coordinates(port, &c); + rc = cxl_endpoint_get_perf_coordinates(port, &ep_c); if (rc) { - dev_dbg(&port->dev, "Failed to retrieve perf coordinates.\n"); + dev_dbg(&port->dev, "Failed to retrieve ep perf coordinates.\n"); + return rc; + } + + rc = cxl_hb_get_perf_coordinates(port, coord); + if (rc) { + dev_dbg(&port->dev, "Failed to retrieve hb perf coordinates.\n"); return rc; } @@ -185,18 +192,19 @@ xa_for_each(dsmas_xa, index, dent) { int qos_class; - dent->coord.read_latency = dent->coord.read_latency + - c.read_latency; - dent->coord.write_latency = dent->coord.write_latency + - c.write_latency; - dent->coord.read_bandwidth = min_t(int, c.read_bandwidth, - dent->coord.read_bandwidth); - dent->coord.write_bandwidth = min_t(int, c.write_bandwidth, - dent->coord.write_bandwidth); - + cxl_coordinates_combine(&dent->coord, &dent->coord, &ep_c); + /* + * Keeping the host bridge coordinates separate from the dsmas + * coordinates in order to allow calculation of access class + * 0 and 1 for region later. + */ + cxl_coordinates_combine(&coord[ACCESS_COORDINATE_LOCAL], + &coord[ACCESS_COORDINATE_LOCAL], + &dent->coord); dent->entries = 1; - rc = cxl_root->ops->qos_class(cxl_root, &dent->coord, 1, - &qos_class); + rc = cxl_root->ops->qos_class(cxl_root, + &coord[ACCESS_COORDINATE_LOCAL], + 1, &qos_class); if (rc != 1) continue; @@ -389,36 +397,38 @@ static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg, const unsigned long end) { + struct acpi_cdat_sslbis_table { + struct acpi_cdat_header header; + struct acpi_cdat_sslbis sslbis_header; + struct acpi_cdat_sslbe entries[]; + } *tbl = (struct acpi_cdat_sslbis_table *)header; + int size = sizeof(header->cdat) + sizeof(tbl->sslbis_header); struct acpi_cdat_sslbis *sslbis; - int size = sizeof(header->cdat) + sizeof(*sslbis); struct cxl_port *port = arg; struct device *dev = &port->dev; - struct acpi_cdat_sslbe *entry; int remain, entries, i; u16 len; len = le16_to_cpu((__force __le16)header->cdat.length); remain = len - size; - if (!remain || remain % sizeof(*entry) || + if (!remain || remain % sizeof(tbl->entries[0]) || (unsigned long)header + len > end) { dev_warn(dev, "Malformed SSLBIS table length: (%u)\n", len); return -EINVAL; } - /* Skip common header */ - sslbis = (struct acpi_cdat_sslbis *)((unsigned long)header + - sizeof(header->cdat)); - + sslbis = &tbl->sslbis_header; /* Unrecognized data type, we can skip */ if (sslbis->data_type > ACPI_HMAT_WRITE_BANDWIDTH) return 0; - entries = remain / sizeof(*entry); - entry = (struct acpi_cdat_sslbe *)((unsigned long)header + sizeof(*sslbis)); + entries = remain / sizeof(tbl->entries[0]); + if (struct_size(tbl, entries, entries) != len) + return -EINVAL; for (i = 0; i < entries; i++) { - u16 x = le16_to_cpu((__force __le16)entry->portx_id); - u16 y = le16_to_cpu((__force __le16)entry->porty_id); + u16 x = le16_to_cpu((__force __le16)tbl->entries[i].portx_id); + u16 y = le16_to_cpu((__force __le16)tbl->entries[i].porty_id); __le64 le_base; __le16 le_val; struct cxl_dport *dport; @@ -448,8 +458,8 @@ break; } - le_base = (__force __le64)sslbis->entry_base_unit; - le_val = (__force __le16)entry->latency_or_bandwidth; + le_base = (__force __le64)tbl->sslbis_header.entry_base_unit; + le_val = (__force __le16)tbl->entries[i].latency_or_bandwidth; if (check_mul_overflow(le64_to_cpu(le_base), le16_to_cpu(le_val), &val)) @@ -462,8 +472,6 @@ sslbis->data_type, val); } - - entry++; } return 0; @@ -484,4 +492,26 @@ } EXPORT_SYMBOL_NS_GPL(cxl_switch_parse_cdat, CXL); +/** + * cxl_coordinates_combine - Combine the two input coordinates + * + * @out: Output coordinate of c1 and c2 combined + * @c1: input coordinates + * @c2: input coordinates + */ +void cxl_coordinates_combine(struct access_coordinate *out, + struct access_coordinate *c1, + struct access_coordinate *c2) +{ + if (c1->write_bandwidth && c2->write_bandwidth) + out->write_bandwidth = min(c1->write_bandwidth, + c2->write_bandwidth); + out->write_latency = c1->write_latency + c2->write_latency; + + if (c1->read_bandwidth && c2->read_bandwidth) + out->read_bandwidth = min(c1->read_bandwidth, + c2->read_bandwidth); + out->read_latency = c1->read_latency + c2->read_latency; +} + MODULE_IMPORT_NS(CXL); --- linux-xilinx-6.8.0.orig/drivers/cxl/core/core.h +++ linux-xilinx-6.8.0/drivers/cxl/core/core.h @@ -27,7 +27,14 @@ int cxl_region_init(void); void cxl_region_exit(void); int cxl_get_poison_by_endpoint(struct cxl_port *port); +struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa); + #else +static inline +struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa) +{ + return NULL; +} static inline int cxl_get_poison_by_endpoint(struct cxl_port *port) { return 0; --- linux-xilinx-6.8.0.orig/drivers/cxl/core/hdm.c +++ linux-xilinx-6.8.0/drivers/cxl/core/hdm.c @@ -52,6 +52,14 @@ struct cxl_dport *dport = NULL; int single_port_map[1]; unsigned long index; + struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev); + + /* + * Capability checks are moot for passthrough decoders, support + * any and all possibilities. + */ + cxlhdm->interleave_mask = ~0U; + cxlhdm->iw_cap_mask = ~0UL; cxlsd = cxl_switch_decoder_alloc(port, 1); if (IS_ERR(cxlsd)) @@ -79,6 +87,11 @@ cxlhdm->interleave_mask |= GENMASK(11, 8); if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_14_12, hdm_cap)) cxlhdm->interleave_mask |= GENMASK(14, 12); + cxlhdm->iw_cap_mask = BIT(1) | BIT(2) | BIT(4) | BIT(8); + if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY, hdm_cap)) + cxlhdm->iw_cap_mask |= BIT(3) | BIT(6) | BIT(12); + if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_16_WAY, hdm_cap)) + cxlhdm->iw_cap_mask |= BIT(16); } static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info) --- linux-xilinx-6.8.0.orig/drivers/cxl/core/mbox.c +++ linux-xilinx-6.8.0/drivers/cxl/core/mbox.c @@ -915,7 +915,7 @@ payload->handles[i++] = gen->hdr.handle; dev_dbg(mds->cxlds.dev, "Event log '%d': Clearing %u\n", log, - le16_to_cpu(payload->handles[i])); + le16_to_cpu(payload->handles[i - 1])); if (i == max_handles) { payload->nr_recs = i; @@ -946,24 +946,22 @@ struct cxl_memdev *cxlmd = mds->cxlds.cxlmd; struct device *dev = mds->cxlds.dev; struct cxl_get_event_payload *payload; - struct cxl_mbox_cmd mbox_cmd; u8 log_type = type; u16 nr_rec; mutex_lock(&mds->event.log_lock); payload = mds->event.buf; - mbox_cmd = (struct cxl_mbox_cmd) { - .opcode = CXL_MBOX_OP_GET_EVENT_RECORD, - .payload_in = &log_type, - .size_in = sizeof(log_type), - .payload_out = payload, - .size_out = mds->payload_size, - .min_out = struct_size(payload, records, 0), - }; - do { int rc, i; + struct cxl_mbox_cmd mbox_cmd = (struct cxl_mbox_cmd) { + .opcode = CXL_MBOX_OP_GET_EVENT_RECORD, + .payload_in = &log_type, + .size_in = sizeof(log_type), + .payload_out = payload, + .size_out = mds->payload_size, + .min_out = struct_size(payload, records, 0), + }; rc = cxl_internal_send_cmd(mds, &mbox_cmd); if (rc) { @@ -1296,7 +1294,6 @@ struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct cxl_mbox_poison_out *po; struct cxl_mbox_poison_in pi; - struct cxl_mbox_cmd mbox_cmd; int nr_records = 0; int rc; @@ -1308,16 +1305,16 @@ pi.offset = cpu_to_le64(offset); pi.length = cpu_to_le64(len / CXL_POISON_LEN_MULT); - mbox_cmd = (struct cxl_mbox_cmd) { - .opcode = CXL_MBOX_OP_GET_POISON, - .size_in = sizeof(pi), - .payload_in = &pi, - .size_out = mds->payload_size, - .payload_out = po, - .min_out = struct_size(po, record, 0), - }; - do { + struct cxl_mbox_cmd mbox_cmd = (struct cxl_mbox_cmd){ + .opcode = CXL_MBOX_OP_GET_POISON, + .size_in = sizeof(pi), + .payload_in = &pi, + .size_out = mds->payload_size, + .payload_out = po, + .min_out = struct_size(po, record, 0), + }; + rc = cxl_internal_send_cmd(mds, &mbox_cmd); if (rc) break; --- linux-xilinx-6.8.0.orig/drivers/cxl/core/memdev.c +++ linux-xilinx-6.8.0/drivers/cxl/core/memdev.c @@ -251,50 +251,6 @@ } EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, CXL); -struct cxl_dpa_to_region_context { - struct cxl_region *cxlr; - u64 dpa; -}; - -static int __cxl_dpa_to_region(struct device *dev, void *arg) -{ - struct cxl_dpa_to_region_context *ctx = arg; - struct cxl_endpoint_decoder *cxled; - u64 dpa = ctx->dpa; - - if (!is_endpoint_decoder(dev)) - return 0; - - cxled = to_cxl_endpoint_decoder(dev); - if (!cxled->dpa_res || !resource_size(cxled->dpa_res)) - return 0; - - if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start) - return 0; - - dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa, - dev_name(&cxled->cxld.region->dev)); - - ctx->cxlr = cxled->cxld.region; - - return 1; -} - -static struct cxl_region *cxl_dpa_to_region(struct cxl_memdev *cxlmd, u64 dpa) -{ - struct cxl_dpa_to_region_context ctx; - struct cxl_port *port; - - ctx = (struct cxl_dpa_to_region_context) { - .dpa = dpa, - }; - port = cxlmd->endpoint; - if (port && is_cxl_endpoint(port) && cxl_num_decoders_committed(port)) - device_for_each_child(&port->dev, &ctx, __cxl_dpa_to_region); - - return ctx.cxlr; -} - static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa) { struct cxl_dev_state *cxlds = cxlmd->cxlds; --- linux-xilinx-6.8.0.orig/drivers/cxl/core/pci.c +++ linux-xilinx-6.8.0/drivers/cxl/core/pci.c @@ -1034,3 +1034,32 @@ return cxl_flit_size(pdev) * MEGA / bw; } + +static int __cxl_endpoint_decoder_reset_detected(struct device *dev, void *data) +{ + struct cxl_port *port = data; + struct cxl_decoder *cxld; + struct cxl_hdm *cxlhdm; + void __iomem *hdm; + u32 ctrl; + + if (!is_endpoint_decoder(dev)) + return 0; + + cxld = to_cxl_decoder(dev); + if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0) + return 0; + + cxlhdm = dev_get_drvdata(&port->dev); + hdm = cxlhdm->regs.hdm_decoder; + ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id)); + + return !FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl); +} + +bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port) +{ + return device_for_each_child(&port->dev, port, + __cxl_endpoint_decoder_reset_detected); +} +EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL); --- linux-xilinx-6.8.0.orig/drivers/cxl/core/pmem.c +++ linux-xilinx-6.8.0/drivers/cxl/core/pmem.c @@ -62,10 +62,14 @@ return is_cxl_nvdimm_bridge(dev); } -struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd) +/** + * cxl_find_nvdimm_bridge() - find a bridge device relative to a port + * @port: any descendant port of an nvdimm-bridge associated + * root-cxl-port + */ +struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port) { - struct cxl_root *cxl_root __free(put_cxl_root) = - find_cxl_root(cxlmd->endpoint); + struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port); struct device *dev; if (!cxl_root) @@ -242,18 +246,20 @@ /** * devm_cxl_add_nvdimm() - add a bridge between a cxl_memdev and an nvdimm + * @parent_port: parent port for the (to be added) @cxlmd endpoint port * @cxlmd: cxl_memdev instance that will perform LIBNVDIMM operations * * Return: 0 on success negative error code on failure. */ -int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd) +int devm_cxl_add_nvdimm(struct cxl_port *parent_port, + struct cxl_memdev *cxlmd) { struct cxl_nvdimm_bridge *cxl_nvb; struct cxl_nvdimm *cxl_nvd; struct device *dev; int rc; - cxl_nvb = cxl_find_nvdimm_bridge(cxlmd); + cxl_nvb = cxl_find_nvdimm_bridge(parent_port); if (!cxl_nvb) return -ENODEV; --- linux-xilinx-6.8.0.orig/drivers/cxl/core/port.c +++ linux-xilinx-6.8.0/drivers/cxl/core/port.c @@ -2096,18 +2096,41 @@ } EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL); -static void combine_coordinates(struct access_coordinate *c1, - struct access_coordinate *c2) +/** + * cxl_hb_get_perf_coordinates - Retrieve performance numbers between initiator + * and host bridge + * + * @port: endpoint cxl_port + * @coord: output access coordinates + * + * Return: errno on failure, 0 on success. + */ +int cxl_hb_get_perf_coordinates(struct cxl_port *port, + struct access_coordinate *coord) { - if (c2->write_bandwidth) - c1->write_bandwidth = min(c1->write_bandwidth, - c2->write_bandwidth); - c1->write_latency += c2->write_latency; - - if (c2->read_bandwidth) - c1->read_bandwidth = min(c1->read_bandwidth, - c2->read_bandwidth); - c1->read_latency += c2->read_latency; + struct cxl_port *iter = port; + struct cxl_dport *dport; + + if (!is_cxl_endpoint(port)) + return -EINVAL; + + dport = iter->parent_dport; + while (iter && !is_cxl_root(to_cxl_port(iter->dev.parent))) { + iter = to_cxl_port(iter->dev.parent); + dport = iter->parent_dport; + } + + coord[ACCESS_COORDINATE_LOCAL] = + dport->hb_coord[ACCESS_COORDINATE_LOCAL]; + coord[ACCESS_COORDINATE_CPU] = + dport->hb_coord[ACCESS_COORDINATE_CPU]; + + return 0; +} + +static bool parent_port_is_cxl_root(struct cxl_port *port) +{ + return is_cxl_root(to_cxl_port(port->dev.parent)); } /** @@ -2129,30 +2152,31 @@ struct cxl_dport *dport; struct pci_dev *pdev; unsigned int bw; + bool is_cxl_root; if (!is_cxl_endpoint(port)) return -EINVAL; - dport = iter->parent_dport; - /* - * Exit the loop when the parent port of the current port is cxl root. - * The iterative loop starts at the endpoint and gathers the - * latency of the CXL link from the current iter to the next downstream - * port each iteration. If the parent is cxl root then there is - * nothing to gather. + * Exit the loop when the parent port of the current iter port is cxl + * root. The iterative loop starts at the endpoint and gathers the + * latency of the CXL link from the current device/port to the connected + * downstream port each iteration. */ - while (iter && !is_cxl_root(to_cxl_port(iter->dev.parent))) { - combine_coordinates(&c, &dport->sw_coord); - c.write_latency += dport->link_latency; - c.read_latency += dport->link_latency; - - iter = to_cxl_port(iter->dev.parent); + do { dport = iter->parent_dport; - } + iter = to_cxl_port(iter->dev.parent); + is_cxl_root = parent_port_is_cxl_root(iter); - /* Augment with the generic port (host bridge) perf data */ - combine_coordinates(&c, &dport->hb_coord); + /* + * There's no valid access_coordinate for a root port since RPs do not + * have CDAT and therefore needs to be skipped. + */ + if (!is_cxl_root) + cxl_coordinates_combine(&c, &c, &dport->sw_coord); + c.write_latency += dport->link_latency; + c.read_latency += dport->link_latency; + } while (!is_cxl_root); /* Get the calculated PCI paths bandwidth */ pdev = to_pci_dev(port->uport_dev->parent); --- linux-xilinx-6.8.0.orig/drivers/cxl/core/region.c +++ linux-xilinx-6.8.0/drivers/cxl/core/region.c @@ -998,6 +998,26 @@ } cxld = cxl_rr->decoder; + /* + * the number of targets should not exceed the target_count + * of the decoder + */ + if (is_switch_decoder(&cxld->dev)) { + struct cxl_switch_decoder *cxlsd; + + cxlsd = to_cxl_switch_decoder(&cxld->dev); + if (cxl_rr->nr_targets > cxlsd->nr_targets) { + dev_dbg(&cxlr->dev, + "%s:%s %s add: %s:%s @ %d overflows targets: %d\n", + dev_name(port->uport_dev), dev_name(&port->dev), + dev_name(&cxld->dev), dev_name(&cxlmd->dev), + dev_name(&cxled->cxld.dev), pos, + cxlsd->nr_targets); + rc = -ENXIO; + goto out_erase; + } + } + rc = cxl_rr_ep_add(cxl_rr, cxled); if (rc) { dev_dbg(&cxlr->dev, @@ -1107,6 +1127,50 @@ return 0; } +static int check_interleave_cap(struct cxl_decoder *cxld, int iw, int ig) +{ + struct cxl_port *port = to_cxl_port(cxld->dev.parent); + struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev); + unsigned int interleave_mask; + u8 eiw; + u16 eig; + int high_pos, low_pos; + + if (!test_bit(iw, &cxlhdm->iw_cap_mask)) + return -ENXIO; + /* + * Per CXL specification r3.1(8.2.4.20.13 Decoder Protection), + * if eiw < 8: + * DPAOFFSET[51: eig + 8] = HPAOFFSET[51: eig + 8 + eiw] + * DPAOFFSET[eig + 7: 0] = HPAOFFSET[eig + 7: 0] + * + * when the eiw is 0, all the bits of HPAOFFSET[51: 0] are used, the + * interleave bits are none. + * + * if eiw >= 8: + * DPAOFFSET[51: eig + 8] = HPAOFFSET[51: eig + eiw] / 3 + * DPAOFFSET[eig + 7: 0] = HPAOFFSET[eig + 7: 0] + * + * when the eiw is 8, all the bits of HPAOFFSET[51: 0] are used, the + * interleave bits are none. + */ + ways_to_eiw(iw, &eiw); + if (eiw == 0 || eiw == 8) + return 0; + + granularity_to_eig(ig, &eig); + if (eiw > 8) + high_pos = eiw + eig - 1; + else + high_pos = eiw + eig + 7; + low_pos = eig + 8; + interleave_mask = GENMASK(high_pos, low_pos); + if (interleave_mask & ~cxlhdm->interleave_mask) + return -ENXIO; + + return 0; +} + static int cxl_port_setup_targets(struct cxl_port *port, struct cxl_region *cxlr, struct cxl_endpoint_decoder *cxled) @@ -1257,6 +1321,15 @@ return -ENXIO; } } else { + rc = check_interleave_cap(cxld, iw, ig); + if (rc) { + dev_dbg(&cxlr->dev, + "%s:%s iw: %d ig: %d is not supported\n", + dev_name(port->uport_dev), + dev_name(&port->dev), iw, ig); + return rc; + } + cxld->interleave_ways = iw; cxld->interleave_granularity = ig; cxld->hpa_range = (struct range) { @@ -1693,6 +1766,15 @@ struct cxl_dport *dport; int rc = -ENXIO; + rc = check_interleave_cap(&cxled->cxld, p->interleave_ways, + p->interleave_granularity); + if (rc) { + dev_dbg(&cxlr->dev, "%s iw: %d ig: %d is not supported\n", + dev_name(&cxled->cxld.dev), p->interleave_ways, + p->interleave_granularity); + return rc; + } + if (cxled->mode != cxlr->mode) { dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n", dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode); @@ -2187,15 +2269,6 @@ struct device *dev; int rc; - switch (mode) { - case CXL_DECODER_RAM: - case CXL_DECODER_PMEM: - break; - default: - dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode); - return ERR_PTR(-EINVAL); - } - cxlr = cxl_region_alloc(cxlrd, id); if (IS_ERR(cxlr)) return cxlr; @@ -2246,6 +2319,15 @@ { int rc; + switch (mode) { + case CXL_DECODER_RAM: + case CXL_DECODER_PMEM: + break; + default: + dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode); + return ERR_PTR(-EINVAL); + } + rc = memregion_alloc(GFP_KERNEL); if (rc < 0) return ERR_PTR(rc); @@ -2510,28 +2592,78 @@ return rc; } +struct cxl_dpa_to_region_context { + struct cxl_region *cxlr; + u64 dpa; +}; + +static int __cxl_dpa_to_region(struct device *dev, void *arg) +{ + struct cxl_dpa_to_region_context *ctx = arg; + struct cxl_endpoint_decoder *cxled; + struct cxl_region *cxlr; + u64 dpa = ctx->dpa; + + if (!is_endpoint_decoder(dev)) + return 0; + + cxled = to_cxl_endpoint_decoder(dev); + if (!cxled || !cxled->dpa_res || !resource_size(cxled->dpa_res)) + return 0; + + if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start) + return 0; + + /* + * Stop the region search (return 1) when an endpoint mapping is + * found. The region may not be fully constructed so offering + * the cxlr in the context structure is not guaranteed. + */ + cxlr = cxled->cxld.region; + if (cxlr) + dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa, + dev_name(&cxlr->dev)); + else + dev_dbg(dev, "dpa:0x%llx mapped in endpoint:%s\n", dpa, + dev_name(dev)); + + ctx->cxlr = cxlr; + + return 1; +} + +struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa) +{ + struct cxl_dpa_to_region_context ctx; + struct cxl_port *port; + + ctx = (struct cxl_dpa_to_region_context) { + .dpa = dpa, + }; + port = cxlmd->endpoint; + if (port && is_cxl_endpoint(port) && cxl_num_decoders_committed(port)) + device_for_each_child(&port->dev, &ctx, __cxl_dpa_to_region); + + return ctx.cxlr; +} + static struct lock_class_key cxl_pmem_region_key; -static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr) +static int cxl_pmem_region_alloc(struct cxl_region *cxlr) { struct cxl_region_params *p = &cxlr->params; struct cxl_nvdimm_bridge *cxl_nvb; - struct cxl_pmem_region *cxlr_pmem; struct device *dev; int i; - down_read(&cxl_region_rwsem); - if (p->state != CXL_CONFIG_COMMIT) { - cxlr_pmem = ERR_PTR(-ENXIO); - goto out; - } + guard(rwsem_read)(&cxl_region_rwsem); + if (p->state != CXL_CONFIG_COMMIT) + return -ENXIO; - cxlr_pmem = kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), - GFP_KERNEL); - if (!cxlr_pmem) { - cxlr_pmem = ERR_PTR(-ENOMEM); - goto out; - } + struct cxl_pmem_region *cxlr_pmem __free(kfree) = + kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), GFP_KERNEL); + if (!cxlr_pmem) + return -ENOMEM; cxlr_pmem->hpa_range.start = p->res->start; cxlr_pmem->hpa_range.end = p->res->end; @@ -2548,11 +2680,9 @@ * bridge for one device is the same for all. */ if (i == 0) { - cxl_nvb = cxl_find_nvdimm_bridge(cxlmd); - if (!cxl_nvb) { - cxlr_pmem = ERR_PTR(-ENODEV); - goto out; - } + cxl_nvb = cxl_find_nvdimm_bridge(cxlmd->endpoint); + if (!cxl_nvb) + return -ENODEV; cxlr->cxl_nvb = cxl_nvb; } m->cxlmd = cxlmd; @@ -2563,18 +2693,16 @@ } dev = &cxlr_pmem->dev; - cxlr_pmem->cxlr = cxlr; - cxlr->cxlr_pmem = cxlr_pmem; device_initialize(dev); lockdep_set_class(&dev->mutex, &cxl_pmem_region_key); device_set_pm_not_required(dev); dev->parent = &cxlr->dev; dev->bus = &cxl_bus_type; dev->type = &cxl_pmem_region_type; -out: - up_read(&cxl_region_rwsem); + cxlr_pmem->cxlr = cxlr; + cxlr->cxlr_pmem = no_free_ptr(cxlr_pmem); - return cxlr_pmem; + return 0; } static void cxl_dax_region_release(struct device *dev) @@ -2691,9 +2819,10 @@ struct device *dev; int rc; - cxlr_pmem = cxl_pmem_region_alloc(cxlr); - if (IS_ERR(cxlr_pmem)) - return PTR_ERR(cxlr_pmem); + rc = cxl_pmem_region_alloc(cxlr); + if (rc) + return rc; + cxlr_pmem = cxlr->cxlr_pmem; cxl_nvb = cxlr->cxl_nvb; dev = &cxlr_pmem->dev; --- linux-xilinx-6.8.0.orig/drivers/cxl/core/regs.c +++ linux-xilinx-6.8.0/drivers/cxl/core/regs.c @@ -271,6 +271,7 @@ static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi, struct cxl_register_map *map) { + u8 reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo); int bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo); u64 offset = ((u64)reg_hi << 32) | (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK); @@ -278,11 +279,11 @@ if (offset > pci_resource_len(pdev, bar)) { dev_warn(&pdev->dev, "BAR%d: %pr: too small (offset: %pa, type: %d)\n", bar, - &pdev->resource[bar], &offset, map->reg_type); + &pdev->resource[bar], &offset, reg_type); return false; } - map->reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo); + map->reg_type = reg_type; map->resource = pci_resource_start(pdev, bar) + offset; map->max_size = pci_resource_len(pdev, bar) - offset; return true; --- linux-xilinx-6.8.0.orig/drivers/cxl/core/trace.h +++ linux-xilinx-6.8.0/drivers/cxl/core/trace.h @@ -253,8 +253,8 @@ * DRAM Event Record * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44 */ -#define CXL_DPA_FLAGS_MASK 0x3F -#define CXL_DPA_MASK (~CXL_DPA_FLAGS_MASK) +#define CXL_DPA_FLAGS_MASK GENMASK(1, 0) +#define CXL_DPA_MASK GENMASK_ULL(63, 6) #define CXL_DPA_VOLATILE BIT(0) #define CXL_DPA_NOT_REPAIRABLE BIT(1) @@ -646,18 +646,18 @@ TRACE_EVENT(cxl_poison, - TP_PROTO(struct cxl_memdev *cxlmd, struct cxl_region *region, + TP_PROTO(struct cxl_memdev *cxlmd, struct cxl_region *cxlr, const struct cxl_poison_record *record, u8 flags, __le64 overflow_ts, enum cxl_poison_trace_type trace_type), - TP_ARGS(cxlmd, region, record, flags, overflow_ts, trace_type), + TP_ARGS(cxlmd, cxlr, record, flags, overflow_ts, trace_type), TP_STRUCT__entry( __string(memdev, dev_name(&cxlmd->dev)) __string(host, dev_name(cxlmd->dev.parent)) __field(u64, serial) __field(u8, trace_type) - __string(region, region) + __string(region, cxlr ? dev_name(&cxlr->dev) : "") __field(u64, overflow_ts) __field(u64, hpa) __field(u64, dpa) @@ -677,10 +677,10 @@ __entry->source = cxl_poison_record_source(record); __entry->trace_type = trace_type; __entry->flags = flags; - if (region) { - __assign_str(region, dev_name(®ion->dev)); - memcpy(__entry->uuid, ®ion->params.uuid, 16); - __entry->hpa = cxl_trace_hpa(region, cxlmd, + if (cxlr) { + __assign_str(region, dev_name(&cxlr->dev)); + memcpy(__entry->uuid, &cxlr->params.uuid, 16); + __entry->hpa = cxl_trace_hpa(cxlr, cxlmd, __entry->dpa); } else { __assign_str(region, ""); --- linux-xilinx-6.8.0.orig/drivers/cxl/cxl.h +++ linux-xilinx-6.8.0/drivers/cxl/cxl.h @@ -44,6 +44,8 @@ #define CXL_HDM_DECODER_TARGET_COUNT_MASK GENMASK(7, 4) #define CXL_HDM_DECODER_INTERLEAVE_11_8 BIT(8) #define CXL_HDM_DECODER_INTERLEAVE_14_12 BIT(9) +#define CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY BIT(11) +#define CXL_HDM_DECODER_INTERLEAVE_16_WAY BIT(12) #define CXL_HDM_DECODER_CTRL_OFFSET 0x4 #define CXL_HDM_DECODER_ENABLE BIT(1) #define CXL_HDM_DECODER0_BASE_LOW_OFFSET(i) (0x20 * (i) + 0x10) @@ -671,7 +673,7 @@ struct cxl_port *port; struct cxl_regs regs; struct access_coordinate sw_coord; - struct access_coordinate hb_coord; + struct access_coordinate hb_coord[ACCESS_COORDINATE_MAX]; long link_latency; }; @@ -845,8 +847,8 @@ struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev); bool is_cxl_nvdimm(struct device *dev); bool is_cxl_nvdimm_bridge(struct device *dev); -int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd); -struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd); +int devm_cxl_add_nvdimm(struct cxl_port *parent_port, struct cxl_memdev *cxlmd); +struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port); #ifdef CONFIG_CXL_REGION bool is_cxl_pmem_region(struct device *dev); @@ -879,9 +881,17 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port, struct access_coordinate *coord); +int cxl_hb_get_perf_coordinates(struct cxl_port *port, + struct access_coordinate *coord); void cxl_memdev_update_perf(struct cxl_memdev *cxlmd); +void cxl_coordinates_combine(struct access_coordinate *out, + struct access_coordinate *c1, + struct access_coordinate *c2); + +bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port); + /* * Unit test builds overrides this to __weak, find the 'strong' version * of these symbols in tools/testing/cxl/. --- linux-xilinx-6.8.0.orig/drivers/cxl/cxlmem.h +++ linux-xilinx-6.8.0/drivers/cxl/cxlmem.h @@ -848,11 +848,21 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd); +/** + * struct cxl_hdm - HDM Decoder registers and cached / decoded capabilities + * @regs: mapped registers, see devm_cxl_setup_hdm() + * @decoder_count: number of decoders for this port + * @target_count: for switch decoders, max downstream port targets + * @interleave_mask: interleave granularity capability, see check_interleave_cap() + * @iw_cap_mask: bitmask of supported interleave ways, see check_interleave_cap() + * @port: mapped cxl_port, see devm_cxl_setup_hdm() + */ struct cxl_hdm { struct cxl_component_regs regs; unsigned int decoder_count; unsigned int target_count; unsigned int interleave_mask; + unsigned long iw_cap_mask; struct cxl_port *port; }; --- linux-xilinx-6.8.0.orig/drivers/cxl/mem.c +++ linux-xilinx-6.8.0/drivers/cxl/mem.c @@ -152,6 +152,15 @@ return -ENXIO; } + if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) { + rc = devm_cxl_add_nvdimm(parent_port, cxlmd); + if (rc) { + if (rc == -ENODEV) + dev_info(dev, "PMEM disabled by platform\n"); + return rc; + } + } + if (dport->rch) endpoint_parent = parent_port->uport_dev; else @@ -174,14 +183,6 @@ if (rc) return rc; - if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) { - rc = devm_cxl_add_nvdimm(cxlmd); - if (rc == -ENODEV) - dev_info(dev, "PMEM disabled by platform\n"); - else - return rc; - } - /* * The kernel may be operating out of CXL memory on this device, * there is no spec defined way to determine whether this device --- linux-xilinx-6.8.0.orig/drivers/cxl/pci.c +++ linux-xilinx-6.8.0/drivers/cxl/pci.c @@ -957,11 +957,33 @@ dev->driver ? "successful" : "failed"); } +static void cxl_reset_done(struct pci_dev *pdev) +{ + struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); + struct cxl_memdev *cxlmd = cxlds->cxlmd; + struct device *dev = &pdev->dev; + + /* + * FLR does not expect to touch the HDM decoders and related + * registers. SBR, however, will wipe all device configurations. + * Issue a warning if there was an active decoder before the reset + * that no longer exists. + */ + guard(device)(&cxlmd->dev); + if (cxlmd->endpoint && + cxl_endpoint_decoder_reset_detected(cxlmd->endpoint)) { + dev_crit(dev, "SBR happened without memory regions removal.\n"); + dev_crit(dev, "System may be unstable if regions hosted system memory.\n"); + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + } +} + static const struct pci_error_handlers cxl_error_handlers = { .error_detected = cxl_error_detected, .slot_reset = cxl_slot_reset, .resume = cxl_error_resume, .cor_error_detected = cxl_cor_error_detected, + .reset_done = cxl_reset_done, }; static struct pci_driver cxl_pci_driver = { --- linux-xilinx-6.8.0.orig/drivers/dma-buf/st-dma-fence-chain.c +++ linux-xilinx-6.8.0/drivers/dma-buf/st-dma-fence-chain.c @@ -84,11 +84,11 @@ return -ENOMEM; chain = mock_chain(NULL, f, 1); - if (!chain) + if (chain) + dma_fence_enable_sw_signaling(chain); + else err = -ENOMEM; - dma_fence_enable_sw_signaling(chain); - dma_fence_signal(f); dma_fence_put(f); --- linux-xilinx-6.8.0.orig/drivers/dma-buf/st-dma-fence.c +++ linux-xilinx-6.8.0/drivers/dma-buf/st-dma-fence.c @@ -540,6 +540,12 @@ t[i].before = pass; t[i].task = kthread_run(thread_signal_callback, &t[i], "dma-fence:%d", i); + if (IS_ERR(t[i].task)) { + ret = PTR_ERR(t[i].task); + while (--i >= 0) + kthread_stop_put(t[i].task); + return ret; + } get_task_struct(t[i].task); } --- linux-xilinx-6.8.0.orig/drivers/dma-buf/sync_debug.c +++ linux-xilinx-6.8.0/drivers/dma-buf/sync_debug.c @@ -110,12 +110,12 @@ seq_printf(s, "%s: %d\n", obj->name, obj->value); - spin_lock_irq(&obj->lock); + spin_lock(&obj->lock); /* Caller already disabled IRQ. */ list_for_each(pos, &obj->pt_list) { struct sync_pt *pt = container_of(pos, struct sync_pt, link); sync_print_fence(s, &pt->base, false); } - spin_unlock_irq(&obj->lock); + spin_unlock(&obj->lock); } static void sync_print_sync_file(struct seq_file *s, --- linux-xilinx-6.8.0.orig/drivers/dma/Kconfig +++ linux-xilinx-6.8.0/drivers/dma/Kconfig @@ -394,7 +394,7 @@ config MCF_EDMA tristate "Freescale eDMA engine support, ColdFire mcf5441x SoCs" - depends on M5441x || COMPILE_TEST + depends on M5441x || (COMPILE_TEST && FSL_EDMA=n) select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help @@ -643,16 +643,16 @@ config TEGRA210_ADMA tristate "NVIDIA Tegra210 ADMA support" - depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST) + depends on (ARCH_TEGRA || COMPILE_TEST) select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help - Support for the NVIDIA Tegra210 ADMA controller driver. The - DMA controller has multiple DMA channels and is used to service - various audio clients in the Tegra210 audio processing engine - (APE). This DMA controller transfers data from memory to - peripheral and vice versa. It does not support memory to - memory data transfer. + Support for the NVIDIA Tegra210/Tegra186/Tegra194/Tegra234 ADMA + controller driver. The DMA controller has multiple DMA channels + and is used to service various audio clients in the Tegra210 + audio processing engine (APE). This DMA controller transfers + data from memory to peripheral and vice versa. It does not + support memory to memory data transfer. config TIMB_DMA tristate "Timberdale FPGA DMA support" @@ -747,6 +747,12 @@ driver provides the dmaengine required by the DisplayPort subsystem display driver. +config XILINX_FRMBUF + tristate "Xilinx Framebuffer" + select DMA_ENGINE + help + Enable support for Xilinx Framebuffer DMA. + # driver files source "drivers/dma/bestcomm/Kconfig" @@ -798,4 +804,18 @@ config DMA_ENGINE_RAID bool +config XILINX_DMATEST + tristate "DMA Test client for AXI DMA and MCDMA" + depends on XILINX_DMA + help + Simple DMA test client. Say N unless you're debugging a + DMA Device driver. + +config XILINX_VDMATEST + tristate "DMA Test client for VDMA" + depends on XILINX_DMA + help + Simple xilinx VDMA test client. Say N unless you're debugging a + DMA Device driver. + endif --- linux-xilinx-6.8.0.orig/drivers/dma/dma-axi-dmac.c +++ linux-xilinx-6.8.0/drivers/dma/dma-axi-dmac.c @@ -1134,8 +1134,8 @@ { struct axi_dmac *dmac = platform_get_drvdata(pdev); - of_dma_controller_free(pdev->dev.of_node); free_irq(dmac->irq, dmac); + of_dma_controller_free(pdev->dev.of_node); tasklet_kill(&dmac->chan.vchan.task); dma_async_device_unregister(&dmac->dma_dev); clk_disable_unprepare(dmac->clk); --- linux-xilinx-6.8.0.orig/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ linux-xilinx-6.8.0/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -302,6 +302,7 @@ kfree(desc); return NULL; } + desc->nr_hw_descs = num; return desc; } @@ -328,7 +329,7 @@ static void axi_desc_put(struct axi_dma_desc *desc) { struct axi_dma_chan *chan = desc->chan; - int count = atomic_read(&chan->descs_allocated); + int count = desc->nr_hw_descs; struct axi_dma_hw_desc *hw_desc; int descs_put; @@ -1139,9 +1140,6 @@ /* Remove the completed descriptor from issued list before completing */ list_del(&vd->node); vchan_cookie_complete(vd); - - /* Submit queued descriptors after processing the completed ones */ - axi_chan_start_first_queued(chan); } out: --- linux-xilinx-6.8.0.orig/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ linux-xilinx-6.8.0/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -104,6 +104,7 @@ u32 completed_blocks; u32 length; u32 period_len; + u32 nr_hw_descs; }; struct axi_dma_chan_config { --- linux-xilinx-6.8.0.orig/drivers/dma/idma64.c +++ linux-xilinx-6.8.0/drivers/dma/idma64.c @@ -171,6 +171,10 @@ u32 status_err; unsigned short i; + /* Since IRQ may be shared, check if DMA controller is powered on */ + if (status == GENMASK(31, 0)) + return IRQ_NONE; + dev_vdbg(idma64->dma.dev, "%s: status=%#x\n", __func__, status); /* Check if we have any interrupt from the DMA controller */ @@ -594,7 +598,9 @@ idma64->dma.dev = chip->sysdev; - dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + ret = dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + if (ret) + return ret; ret = dma_async_device_register(&idma64->dma); if (ret) --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/cdev.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/cdev.c @@ -342,7 +342,7 @@ if (!evl) return; - spin_lock(&evl->lock); + mutex_lock(&evl->lock); status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET); t = status.tail; h = status.head; @@ -354,9 +354,8 @@ set_bit(h, evl->bmap); h = (h + 1) % size; } - spin_unlock(&evl->lock); - drain_workqueue(wq->wq); + mutex_unlock(&evl->lock); } static int idxd_cdev_release(struct inode *node, struct file *filep) @@ -401,6 +400,18 @@ int rc; dev_dbg(&pdev->dev, "%s called\n", __func__); + + /* + * Due to an erratum in some of the devices supported by the driver, + * direct user submission to the device can be unsafe. + * (See document INTEL-SA-01084) + * + * For the devices that exhibit this behavior, require that the user + * has CAP_SYS_RAWIO capabilities. + */ + if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO)) + return -EPERM; + rc = check_vma(wq, vma, __func__); if (rc < 0) return rc; @@ -415,6 +426,70 @@ vma->vm_page_prot); } +static int idxd_submit_user_descriptor(struct idxd_user_context *ctx, + struct dsa_hw_desc __user *udesc) +{ + struct idxd_wq *wq = ctx->wq; + struct idxd_dev *idxd_dev = &wq->idxd->idxd_dev; + const uint64_t comp_addr_align = is_dsa_dev(idxd_dev) ? 0x20 : 0x40; + void __iomem *portal = idxd_wq_portal_addr(wq); + struct dsa_hw_desc descriptor __aligned(64); + int rc; + + rc = copy_from_user(&descriptor, udesc, sizeof(descriptor)); + if (rc) + return -EFAULT; + + /* + * DSA devices are capable of indirect ("batch") command submission. + * On devices where direct user submissions are not safe, we cannot + * allow this since there is no good way for us to verify these + * indirect commands. + */ + if (is_dsa_dev(idxd_dev) && descriptor.opcode == DSA_OPCODE_BATCH && + !wq->idxd->user_submission_safe) + return -EINVAL; + /* + * As per the programming specification, the completion address must be + * aligned to 32 or 64 bytes. If this is violated the hardware + * engine can get very confused (security issue). + */ + if (!IS_ALIGNED(descriptor.completion_addr, comp_addr_align)) + return -EINVAL; + + if (wq_dedicated(wq)) + iosubmit_cmds512(portal, &descriptor, 1); + else { + descriptor.priv = 0; + descriptor.pasid = ctx->pasid; + rc = idxd_enqcmds(wq, portal, &descriptor); + if (rc < 0) + return rc; + } + + return 0; +} + +static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_t len, + loff_t *unused) +{ + struct dsa_hw_desc __user *udesc = (struct dsa_hw_desc __user *)buf; + struct idxd_user_context *ctx = filp->private_data; + ssize_t written = 0; + int i; + + for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) { + int rc = idxd_submit_user_descriptor(ctx, udesc + i); + + if (rc) + return written ? written : rc; + + written += sizeof(struct dsa_hw_desc); + } + + return written; +} + static __poll_t idxd_cdev_poll(struct file *filp, struct poll_table_struct *wait) { @@ -437,6 +512,7 @@ .open = idxd_cdev_open, .release = idxd_cdev_release, .mmap = idxd_cdev_mmap, + .write = idxd_cdev_write, .poll = idxd_cdev_poll, }; @@ -501,7 +577,6 @@ struct idxd_cdev *idxd_cdev; idxd_cdev = wq->idxd_cdev; - ida_destroy(&file_ida); wq->idxd_cdev = NULL; cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev)); put_device(cdev_dev(idxd_cdev)); --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/debugfs.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/debugfs.c @@ -66,7 +66,7 @@ if (!evl || !evl->log) return 0; - spin_lock(&evl->lock); + mutex_lock(&evl->lock); evl_status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET); t = evl_status.tail; @@ -87,7 +87,7 @@ dump_event_entry(idxd, s, i, &count, processed); } - spin_unlock(&evl->lock); + mutex_unlock(&evl->lock); return 0; } --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/device.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/device.c @@ -775,7 +775,7 @@ goto err_alloc; } - spin_lock(&evl->lock); + mutex_lock(&evl->lock); evl->log = addr; evl->dma = dma_addr; evl->log_size = size; @@ -796,7 +796,7 @@ gencfg.evl_en = 1; iowrite32(gencfg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET); - spin_unlock(&evl->lock); + mutex_unlock(&evl->lock); return 0; err_alloc: @@ -819,7 +819,7 @@ if (!gencfg.evl_en) return; - spin_lock(&evl->lock); + mutex_lock(&evl->lock); gencfg.evl_en = 0; iowrite32(gencfg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET); @@ -836,7 +836,7 @@ evl_dma = evl->dma; evl->log = NULL; evl->size = IDXD_EVL_SIZE_MIN; - spin_unlock(&evl->lock); + mutex_unlock(&evl->lock); dma_free_coherent(dev, evl_log_size, evl_log, evl_dma); } --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/idxd.h +++ linux-xilinx-6.8.0/drivers/dma/idxd/idxd.h @@ -288,12 +288,13 @@ int evl_cr_off; int cr_status_off; int cr_result_off; + bool user_submission_safe; load_device_defaults_fn_t load_device_defaults; }; struct idxd_evl { /* Lock to protect event log access. */ - spinlock_t lock; + struct mutex lock; void *log; dma_addr_t dma; /* Total size of event log = number of entries * entry size. */ @@ -374,6 +375,8 @@ struct dentry *dbgfs_dir; struct dentry *dbgfs_evl_file; + + bool user_submission_safe; }; static inline unsigned int evl_ent_size(struct idxd_device *idxd) --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/init.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/init.c @@ -47,6 +47,7 @@ .align = 32, .dev_type = &dsa_device_type, .evl_cr_off = offsetof(struct dsa_evl_entry, cr), + .user_submission_safe = false, /* See INTEL-SA-01084 erratum */ .cr_status_off = offsetof(struct dsa_completion_record, status), .cr_result_off = offsetof(struct dsa_completion_record, result), }, @@ -57,6 +58,7 @@ .align = 64, .dev_type = &iax_device_type, .evl_cr_off = offsetof(struct iax_evl_entry, cr), + .user_submission_safe = false, /* See INTEL-SA-01084 erratum */ .cr_status_off = offsetof(struct iax_completion_record, status), .cr_result_off = offsetof(struct iax_completion_record, error_code), .load_device_defaults = idxd_load_iaa_device_defaults, @@ -354,7 +356,7 @@ if (!evl) return -ENOMEM; - spin_lock_init(&evl->lock); + mutex_init(&evl->lock); evl->size = IDXD_EVL_SIZE_MIN; idxd_name = dev_name(idxd_confdev(idxd)); @@ -774,6 +776,8 @@ dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n", idxd->hw.version); + idxd->user_submission_safe = data->user_submission_safe; + return 0; err_dev_register: --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/irq.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/irq.c @@ -363,7 +363,7 @@ evl_status.bits = 0; evl_status.int_pending = 1; - spin_lock(&evl->lock); + mutex_lock(&evl->lock); /* Clear interrupt pending bit */ iowrite32(evl_status.bits_upper32, idxd->reg_base + IDXD_EVLSTATUS_OFFSET + sizeof(u32)); @@ -380,7 +380,7 @@ evl_status.head = h; iowrite32(evl_status.bits_lower32, idxd->reg_base + IDXD_EVLSTATUS_OFFSET); - spin_unlock(&evl->lock); + mutex_unlock(&evl->lock); } irqreturn_t idxd_misc_thread(int vec, void *data) @@ -611,11 +611,13 @@ spin_unlock(&irq_entry->list_lock); - list_for_each_entry(desc, &flist, list) { + list_for_each_entry_safe(desc, n, &flist, list) { /* * Check against the original status as ABORT is software defined * and 0xff, which DSA_COMP_STATUS_MASK can mask out. */ + list_del(&desc->list); + if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { idxd_desc_complete(desc, IDXD_COMPLETE_ABORT, true); continue; --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/perfmon.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/perfmon.c @@ -528,14 +528,11 @@ return 0; target = cpumask_any_but(cpu_online_mask, cpu); - /* migrate events if there is a valid target */ - if (target < nr_cpu_ids) + if (target < nr_cpu_ids) { cpumask_set_cpu(target, &perfmon_dsa_cpu_mask); - else - target = -1; - - perf_pmu_migrate_context(&idxd_pmu->pmu, cpu, target); + perf_pmu_migrate_context(&idxd_pmu->pmu, cpu, target); + } return 0; } --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/registers.h +++ linux-xilinx-6.8.0/drivers/dma/idxd/registers.h @@ -6,9 +6,6 @@ #include /* PCI Config */ -#define PCI_DEVICE_ID_INTEL_DSA_SPR0 0x0b25 -#define PCI_DEVICE_ID_INTEL_IAX_SPR0 0x0cfe - #define DEVICE_VERSION_1 0x100 #define DEVICE_VERSION_2 0x200 --- linux-xilinx-6.8.0.orig/drivers/dma/idxd/sysfs.c +++ linux-xilinx-6.8.0/drivers/dma/idxd/sysfs.c @@ -1197,12 +1197,35 @@ static struct device_attribute dev_attr_wq_enqcmds_retries = __ATTR(enqcmds_retries, 0644, wq_enqcmds_retries_show, wq_enqcmds_retries_store); +static ssize_t op_cap_show_common(struct device *dev, char *buf, unsigned long *opcap_bmap) +{ + ssize_t pos; + int i; + + pos = 0; + for (i = IDXD_MAX_OPCAP_BITS/64 - 1; i >= 0; i--) { + unsigned long val = opcap_bmap[i]; + + /* On systems where direct user submissions are not safe, we need to clear out + * the BATCH capability from the capability mask in sysfs since we cannot support + * that command on such systems. + */ + if (i == DSA_OPCODE_BATCH/64 && !confdev_to_idxd(dev)->user_submission_safe) + clear_bit(DSA_OPCODE_BATCH % 64, &val); + + pos += sysfs_emit_at(buf, pos, "%*pb", 64, &val); + pos += sysfs_emit_at(buf, pos, "%c", i == 0 ? '\n' : ','); + } + + return pos; +} + static ssize_t wq_op_config_show(struct device *dev, struct device_attribute *attr, char *buf) { struct idxd_wq *wq = confdev_to_wq(dev); - return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, wq->opcap_bmap); + return op_cap_show_common(dev, buf, wq->opcap_bmap); } static int idxd_verify_supported_opcap(struct idxd_device *idxd, unsigned long *opmask) @@ -1455,7 +1478,7 @@ { struct idxd_device *idxd = confdev_to_idxd(dev); - return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap); + return op_cap_show_common(dev, buf, idxd->opcap_bmap); } static DEVICE_ATTR_RO(op_cap); --- linux-xilinx-6.8.0.orig/drivers/dma/ioat/init.c +++ linux-xilinx-6.8.0/drivers/dma/ioat/init.c @@ -534,18 +534,6 @@ return err; } -static int ioat_register(struct ioatdma_device *ioat_dma) -{ - int err = dma_async_device_register(&ioat_dma->dma_dev); - - if (err) { - ioat_disable_interrupts(ioat_dma); - dma_pool_destroy(ioat_dma->completion_pool); - } - - return err; -} - static void ioat_dma_remove(struct ioatdma_device *ioat_dma) { struct dma_device *dma = &ioat_dma->dma_dev; @@ -1181,9 +1169,9 @@ ioat_chan->reg_base + IOAT_DCACTRL_OFFSET); } - err = ioat_register(ioat_dma); + err = dma_async_device_register(&ioat_dma->dma_dev); if (err) - return err; + goto err_disable_interrupts; ioat_kobject_add(ioat_dma, &ioat_ktype); @@ -1192,20 +1180,29 @@ /* disable relaxed ordering */ err = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &val16); - if (err) - return pcibios_err_to_errno(err); + if (err) { + err = pcibios_err_to_errno(err); + goto err_disable_interrupts; + } /* clear relaxed ordering enable */ val16 &= ~PCI_EXP_DEVCTL_RELAX_EN; err = pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, val16); - if (err) - return pcibios_err_to_errno(err); + if (err) { + err = pcibios_err_to_errno(err); + goto err_disable_interrupts; + } if (ioat_dma->cap & IOAT_CAP_DPS) writeb(ioat_pending_level + 1, ioat_dma->reg_base + IOAT_PREFETCH_LIMIT_OFFSET); return 0; + +err_disable_interrupts: + ioat_disable_interrupts(ioat_dma); + dma_pool_destroy(ioat_dma->completion_pool); + return err; } static void ioat_shutdown(struct pci_dev *pdev) @@ -1350,6 +1347,8 @@ void __iomem * const *iomap; struct device *dev = &pdev->dev; struct ioatdma_device *device; + unsigned int i; + u8 version; int err; err = pcim_enable_device(pdev); @@ -1363,6 +1362,10 @@ if (!iomap) return -ENOMEM; + version = readb(iomap[IOAT_MMIO_BAR] + IOAT_VER_OFFSET); + if (version < IOAT_VER_3_0) + return -ENODEV; + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (err) return err; @@ -1373,17 +1376,18 @@ pci_set_master(pdev); pci_set_drvdata(pdev, device); - device->version = readb(device->reg_base + IOAT_VER_OFFSET); + device->version = version; if (device->version >= IOAT_VER_3_4) ioat_dca_enabled = 0; - if (device->version >= IOAT_VER_3_0) { - if (is_skx_ioat(pdev)) - device->version = IOAT_VER_3_2; - err = ioat3_dma_probe(device, ioat_dca_enabled); - } else - return -ENODEV; + if (is_skx_ioat(pdev)) + device->version = IOAT_VER_3_2; + + err = ioat3_dma_probe(device, ioat_dca_enabled); if (err) { + for (i = 0; i < IOAT_MAX_CHANS; i++) + kfree(device->idx[i]); + kfree(device); dev_err(dev, "Intel(R) I/OAT DMA Engine init failed\n"); return -ENODEV; } @@ -1445,6 +1449,7 @@ static void __exit ioat_exit_module(void) { pci_unregister_driver(&ioat_pci_driver); + kmem_cache_destroy(ioat_sed_cache); kmem_cache_destroy(ioat_cache); } module_exit(ioat_exit_module); --- linux-xilinx-6.8.0.orig/drivers/dma/owl-dma.c +++ linux-xilinx-6.8.0/drivers/dma/owl-dma.c @@ -250,7 +250,7 @@ else regval &= ~val; - writel(val, pchan->base + reg); + writel(regval, pchan->base + reg); } static void pchan_writel(struct owl_dma_pchan *pchan, u32 reg, u32 data) @@ -274,7 +274,7 @@ else regval &= ~val; - writel(val, od->base + reg); + writel(regval, od->base + reg); } static void dma_writel(struct owl_dma *od, u32 reg, u32 data) --- linux-xilinx-6.8.0.orig/drivers/dma/pl330.c +++ linux-xilinx-6.8.0/drivers/dma/pl330.c @@ -1053,9 +1053,6 @@ thrd->req_running = idx; - if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM) - UNTIL(thrd, PL330_STATE_WFP); - return true; } --- linux-xilinx-6.8.0.orig/drivers/dma/tegra186-gpc-dma.c +++ linux-xilinx-6.8.0/drivers/dma/tegra186-gpc-dma.c @@ -746,6 +746,9 @@ bytes_xfer = dma_desc->bytes_xfer + sg_req[dma_desc->sg_idx].len - (wcount * 4); + if (dma_desc->bytes_req == bytes_xfer) + return 0; + residual = dma_desc->bytes_req - (bytes_xfer % dma_desc->bytes_req); return residual; --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/Makefile +++ linux-xilinx-6.8.0/drivers/dma/xilinx/Makefile @@ -1,5 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_XILINX_DMATEST) += axidmatest.o +obj-$(CONFIG_XILINX_VDMATEST) += vdmatest.o obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o obj-$(CONFIG_XILINX_XDMA) += xdma.o obj-$(CONFIG_XILINX_ZYNQMP_DMA) += zynqmp_dma.o obj-$(CONFIG_XILINX_ZYNQMP_DPDMA) += xilinx_dpdma.o +obj-$(CONFIG_XILINX_FRMBUF) += xilinx_frmbuf.o --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/axidmatest.c +++ linux-xilinx-6.8.0/drivers/dma/xilinx/axidmatest.c @@ -0,0 +1,698 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * XILINX AXI DMA and MCDMA Engine test module + * + * Copyright (C) 2010 Xilinx, Inc. All rights reserved. + * + * Based on Atmel DMA Test Client + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int test_buf_size = 16384; +module_param(test_buf_size, uint, 0444); +MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); + +static unsigned int iterations = 5; +module_param(iterations, uint, 0444); +MODULE_PARM_DESC(iterations, + "Iterations before stopping test (default: infinite)"); + +/* + * Initialization patterns. All bytes in the source buffer has bit 7 + * set, all bytes in the destination buffer has bit 7 cleared. + * + * Bit 6 is set for all bytes which are to be copied by the DMA + * engine. Bit 5 is set for all bytes which are to be overwritten by + * the DMA engine. + * + * The remaining bits are the inverse of a counter which increments by + * one for each byte address. + */ +#define PATTERN_SRC 0x80 +#define PATTERN_DST 0x00 +#define PATTERN_COPY 0x40 +#define PATTERN_OVERWRITE 0x20 +#define PATTERN_COUNT_MASK 0x1f + +#define XILINX_DMATEST_BD_CNT 11 + +struct dmatest_slave_thread { + struct list_head node; + struct task_struct *task; + struct dma_chan *tx_chan; + struct dma_chan *rx_chan; + u8 **srcs; + u8 **dsts; + enum dma_transaction_type type; + bool done; +}; + +struct dmatest_chan { + struct list_head node; + struct dma_chan *chan; + struct list_head threads; +}; + +/* + * These are protected by dma_list_mutex since they're only used by + * the DMA filter function callback + */ +static DECLARE_WAIT_QUEUE_HEAD(thread_wait); +static LIST_HEAD(dmatest_channels); +static unsigned int nr_channels; + +static unsigned long long dmatest_persec(s64 runtime, unsigned int val) +{ + unsigned long long per_sec = 1000000; + + if (runtime <= 0) + return 0; + + /* drop precision until runtime is 32-bits */ + while (runtime > UINT_MAX) { + runtime >>= 1; + per_sec <<= 1; + } + + per_sec *= val; + do_div(per_sec, runtime); + return per_sec; +} + +static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len) +{ + return dmatest_persec(runtime, len >> 10); +} + +static bool is_threaded_test_run(struct dmatest_chan *tx_dtc, + struct dmatest_chan *rx_dtc) +{ + struct dmatest_slave_thread *thread; + int ret = false; + + list_for_each_entry(thread, &tx_dtc->threads, node) { + if (!thread->done) + ret = true; + } + + list_for_each_entry(thread, &rx_dtc->threads, node) { + if (!thread->done) + ret = true; + } + return ret; +} + +static unsigned long dmatest_random(void) +{ + unsigned long buf; + + get_random_bytes(&buf, sizeof(buf)); + return buf; +} + +static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len) +{ + unsigned int i; + u8 *buf; + + for (; (buf = *bufs); bufs++) { + for (i = 0; i < start; i++) + buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); + for ( ; i < start + len; i++) + buf[i] = PATTERN_SRC | PATTERN_COPY + | (~i & PATTERN_COUNT_MASK); + for ( ; i < test_buf_size; i++) + buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); + } +} + +static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len) +{ + unsigned int i; + u8 *buf; + + for (; (buf = *bufs); bufs++) { + for (i = 0; i < start; i++) + buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); + for ( ; i < start + len; i++) + buf[i] = PATTERN_DST | PATTERN_OVERWRITE + | (~i & PATTERN_COUNT_MASK); + for ( ; i < test_buf_size; i++) + buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); + } +} + +static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index, + unsigned int counter, bool is_srcbuf) +{ + u8 diff = actual ^ pattern; + u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); + const char *thread_name = current->comm; + + if (is_srcbuf) + pr_warn("%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n", + thread_name, index, expected, actual); + else if ((pattern & PATTERN_COPY) && + (diff & (PATTERN_COPY | PATTERN_OVERWRITE))) + pr_warn("%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n", + thread_name, index, expected, actual); + else if (diff & PATTERN_SRC) + pr_warn("%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n", + thread_name, index, expected, actual); + else + pr_warn("%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n", + thread_name, index, expected, actual); +} + +static unsigned int dmatest_verify(u8 **bufs, unsigned int start, + unsigned int end, unsigned int counter, + u8 pattern, bool is_srcbuf) +{ + unsigned int i; + unsigned int error_count = 0; + u8 actual; + u8 expected; + u8 *buf; + unsigned int counter_orig = counter; + + for (; (buf = *bufs); bufs++) { + counter = counter_orig; + for (i = start; i < end; i++) { + actual = buf[i]; + expected = pattern | (~counter & PATTERN_COUNT_MASK); + if (actual != expected) { + if (error_count < 32) + dmatest_mismatch(actual, pattern, i, + counter, is_srcbuf); + error_count++; + } + counter++; + } + } + + if (error_count > 32) + pr_warn("%s: %u errors suppressed\n", + current->comm, error_count - 32); + + return error_count; +} + +static void dmatest_slave_tx_callback(void *completion) +{ + complete(completion); +} + +static void dmatest_slave_rx_callback(void *completion) +{ + complete(completion); +} + +/* Function for slave transfers + * Each thread requires 2 channels, one for transmit, and one for receive + */ +static int dmatest_slave_func(void *data) +{ + struct dmatest_slave_thread *thread = data; + struct dma_chan *tx_chan; + struct dma_chan *rx_chan; + const char *thread_name; + unsigned int src_off, dst_off, len; + unsigned int error_count; + unsigned int failed_tests = 0; + unsigned int total_tests = 0; + dma_cookie_t tx_cookie; + dma_cookie_t rx_cookie; + enum dma_status status; + enum dma_ctrl_flags flags; + int ret; + int src_cnt; + int dst_cnt; + int bd_cnt = XILINX_DMATEST_BD_CNT; + int i; + + ktime_t ktime, start, diff; + ktime_t filltime = 0; + ktime_t comparetime = 0; + s64 runtime = 0; + unsigned long long total_len = 0; + thread_name = current->comm; + ret = -ENOMEM; + + + /* Ensure that all previous reads are complete */ + smp_rmb(); + tx_chan = thread->tx_chan; + rx_chan = thread->rx_chan; + dst_cnt = bd_cnt; + src_cnt = bd_cnt; + + thread->srcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL); + if (!thread->srcs) + goto err_srcs; + for (i = 0; i < src_cnt; i++) { + thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL); + if (!thread->srcs[i]) + goto err_srcbuf; + } + thread->srcs[i] = NULL; + + thread->dsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL); + if (!thread->dsts) + goto err_dsts; + for (i = 0; i < dst_cnt; i++) { + thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL); + if (!thread->dsts[i]) + goto err_dstbuf; + } + thread->dsts[i] = NULL; + + set_user_nice(current, 10); + + flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; + + ktime = ktime_get(); + while (!kthread_should_stop() && + !(iterations && total_tests >= iterations)) { + struct dma_device *tx_dev = tx_chan->device; + struct dma_device *rx_dev = rx_chan->device; + struct dma_async_tx_descriptor *txd = NULL; + struct dma_async_tx_descriptor *rxd = NULL; + dma_addr_t dma_srcs[XILINX_DMATEST_BD_CNT]; + dma_addr_t dma_dsts[XILINX_DMATEST_BD_CNT]; + struct completion rx_cmp; + struct completion tx_cmp; + unsigned long rx_tmo = + msecs_to_jiffies(300000); /* RX takes longer */ + unsigned long tx_tmo = msecs_to_jiffies(30000); + u8 align = 0; + struct scatterlist tx_sg[XILINX_DMATEST_BD_CNT]; + struct scatterlist rx_sg[XILINX_DMATEST_BD_CNT]; + + total_tests++; + + /* honor larger alignment restrictions */ + align = tx_dev->copy_align; + if (rx_dev->copy_align > align) + align = rx_dev->copy_align; + + if (1 << align > test_buf_size) { + pr_err("%u-byte buffer too small for %d-byte alignment\n", + test_buf_size, 1 << align); + break; + } + + len = dmatest_random() % test_buf_size + 1; + len = (len >> align) << align; + if (!len) + len = 1 << align; + src_off = dmatest_random() % (test_buf_size - len + 1); + dst_off = dmatest_random() % (test_buf_size - len + 1); + + src_off = (src_off >> align) << align; + dst_off = (dst_off >> align) << align; + + start = ktime_get(); + dmatest_init_srcs(thread->srcs, src_off, len); + dmatest_init_dsts(thread->dsts, dst_off, len); + diff = ktime_sub(ktime_get(), start); + filltime = ktime_add(filltime, diff); + + for (i = 0; i < src_cnt; i++) { + u8 *buf = thread->srcs[i] + src_off; + + dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len, + DMA_TO_DEVICE); + } + + for (i = 0; i < dst_cnt; i++) { + dma_dsts[i] = dma_map_single(rx_dev->dev, + thread->dsts[i], + test_buf_size, + DMA_BIDIRECTIONAL); + } + + sg_init_table(tx_sg, bd_cnt); + sg_init_table(rx_sg, bd_cnt); + + for (i = 0; i < bd_cnt; i++) { + sg_dma_address(&tx_sg[i]) = dma_srcs[i]; + sg_dma_address(&rx_sg[i]) = dma_dsts[i] + dst_off; + + sg_dma_len(&tx_sg[i]) = len; + sg_dma_len(&rx_sg[i]) = len; + total_len += len; + } + + rxd = rx_dev->device_prep_slave_sg(rx_chan, rx_sg, bd_cnt, + DMA_DEV_TO_MEM, flags, NULL); + + txd = tx_dev->device_prep_slave_sg(tx_chan, tx_sg, bd_cnt, + DMA_MEM_TO_DEV, flags, NULL); + + if (!rxd || !txd) { + for (i = 0; i < src_cnt; i++) + dma_unmap_single(tx_dev->dev, dma_srcs[i], len, + DMA_TO_DEVICE); + for (i = 0; i < dst_cnt; i++) + dma_unmap_single(rx_dev->dev, dma_dsts[i], + test_buf_size, + DMA_BIDIRECTIONAL); + pr_warn("%s: #%u: prep error with src_off=0x%x ", + thread_name, total_tests - 1, src_off); + pr_warn("dst_off=0x%x len=0x%x\n", + dst_off, len); + msleep(100); + failed_tests++; + continue; + } + + init_completion(&rx_cmp); + rxd->callback = dmatest_slave_rx_callback; + rxd->callback_param = &rx_cmp; + rx_cookie = rxd->tx_submit(rxd); + + init_completion(&tx_cmp); + txd->callback = dmatest_slave_tx_callback; + txd->callback_param = &tx_cmp; + tx_cookie = txd->tx_submit(txd); + + if (dma_submit_error(rx_cookie) || + dma_submit_error(tx_cookie)) { + pr_warn("%s: #%u: submit error %d/%d with src_off=0x%x ", + thread_name, total_tests - 1, + rx_cookie, tx_cookie, src_off); + pr_warn("dst_off=0x%x len=0x%x\n", + dst_off, len); + msleep(100); + failed_tests++; + continue; + } + dma_async_issue_pending(rx_chan); + dma_async_issue_pending(tx_chan); + + tx_tmo = wait_for_completion_timeout(&tx_cmp, tx_tmo); + + status = dma_async_is_tx_complete(tx_chan, tx_cookie, + NULL, NULL); + + if (tx_tmo == 0) { + pr_warn("%s: #%u: tx test timed out\n", + thread_name, total_tests - 1); + failed_tests++; + continue; + } else if (status != DMA_COMPLETE) { + pr_warn("%s: #%u: tx got completion callback, ", + thread_name, total_tests - 1); + pr_warn("but status is \'%s\'\n", + status == DMA_ERROR ? "error" : + "in progress"); + failed_tests++; + continue; + } + + rx_tmo = wait_for_completion_timeout(&rx_cmp, rx_tmo); + status = dma_async_is_tx_complete(rx_chan, rx_cookie, + NULL, NULL); + + if (rx_tmo == 0) { + pr_warn("%s: #%u: rx test timed out\n", + thread_name, total_tests - 1); + failed_tests++; + continue; + } else if (status != DMA_COMPLETE) { + pr_warn("%s: #%u: rx got completion callback, ", + thread_name, total_tests - 1); + pr_warn("but status is \'%s\'\n", + status == DMA_ERROR ? "error" : + "in progress"); + failed_tests++; + continue; + } + + /* Unmap by myself */ + for (i = 0; i < dst_cnt; i++) + dma_unmap_single(rx_dev->dev, dma_dsts[i], + test_buf_size, DMA_BIDIRECTIONAL); + + error_count = 0; + start = ktime_get(); + pr_debug("%s: verifying source buffer...\n", thread_name); + error_count += dmatest_verify(thread->srcs, 0, src_off, + 0, PATTERN_SRC, true); + error_count += dmatest_verify(thread->srcs, src_off, + src_off + len, src_off, + PATTERN_SRC | PATTERN_COPY, true); + error_count += dmatest_verify(thread->srcs, src_off + len, + test_buf_size, src_off + len, + PATTERN_SRC, true); + + pr_debug("%s: verifying dest buffer...\n", + thread->task->comm); + error_count += dmatest_verify(thread->dsts, 0, dst_off, + 0, PATTERN_DST, false); + error_count += dmatest_verify(thread->dsts, dst_off, + dst_off + len, src_off, + PATTERN_SRC | PATTERN_COPY, false); + error_count += dmatest_verify(thread->dsts, dst_off + len, + test_buf_size, dst_off + len, + PATTERN_DST, false); + diff = ktime_sub(ktime_get(), start); + comparetime = ktime_add(comparetime, diff); + + if (error_count) { + pr_warn("%s: #%u: %u errors with ", + thread_name, total_tests - 1, error_count); + pr_warn("src_off=0x%x dst_off=0x%x len=0x%x\n", + src_off, dst_off, len); + failed_tests++; + } else { + pr_debug("%s: #%u: No errors with ", + thread_name, total_tests - 1); + pr_debug("src_off=0x%x dst_off=0x%x len=0x%x\n", + src_off, dst_off, len); + } + } + + ktime = ktime_sub(ktime_get(), ktime); + ktime = ktime_sub(ktime, comparetime); + ktime = ktime_sub(ktime, filltime); + runtime = ktime_to_us(ktime); + + ret = 0; + for (i = 0; thread->dsts[i]; i++) + kfree(thread->dsts[i]); +err_dstbuf: + kfree(thread->dsts); +err_dsts: + for (i = 0; thread->srcs[i]; i++) + kfree(thread->srcs[i]); +err_srcbuf: + kfree(thread->srcs); +err_srcs: + pr_notice("%s: terminating after %u tests, %u failures %llu iops %llu KB/s (status %d)\n", + thread_name, total_tests, failed_tests, + dmatest_persec(runtime, total_tests), + dmatest_KBs(runtime, total_len), ret); + + thread->done = true; + wake_up(&thread_wait); + + return ret; +} + +static void dmatest_cleanup_channel(struct dmatest_chan *dtc) +{ + struct dmatest_slave_thread *thread; + struct dmatest_slave_thread *_thread; + int ret; + + list_for_each_entry_safe(thread, _thread, &dtc->threads, node) { + ret = kthread_stop(thread->task); + pr_debug("dmatest: thread %s exited with status %d\n", + thread->task->comm, ret); + list_del(&thread->node); + put_task_struct(thread->task); + kfree(thread); + } + kfree(dtc); +} + +static int dmatest_add_slave_threads(struct dmatest_chan *tx_dtc, + struct dmatest_chan *rx_dtc) +{ + struct dmatest_slave_thread *thread; + struct dma_chan *tx_chan = tx_dtc->chan; + struct dma_chan *rx_chan = rx_dtc->chan; + int ret; + + thread = kzalloc(sizeof(struct dmatest_slave_thread), GFP_KERNEL); + if (!thread) { + pr_warn("dmatest: No memory for slave thread %s-%s\n", + dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + } + + thread->tx_chan = tx_chan; + thread->rx_chan = rx_chan; + thread->type = (enum dma_transaction_type)DMA_SLAVE; + + /* Ensure that all previous writes are complete */ + smp_wmb(); + thread->task = kthread_run(dmatest_slave_func, thread, "%s-%s", + dma_chan_name(tx_chan), + dma_chan_name(rx_chan)); + ret = PTR_ERR(thread->task); + if (IS_ERR(thread->task)) { + pr_warn("dmatest: Failed to run thread %s-%s\n", + dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + kfree(thread); + return ret; + } + + /* srcbuf and dstbuf are allocated by the thread itself */ + get_task_struct(thread->task); + list_add_tail(&thread->node, &tx_dtc->threads); + + /* Added one thread with 2 channels */ + return 1; +} + +static int dmatest_add_slave_channels(struct dma_chan *tx_chan, + struct dma_chan *rx_chan) +{ + struct dmatest_chan *tx_dtc; + struct dmatest_chan *rx_dtc; + unsigned int thread_count = 0; + + tx_dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); + if (!tx_dtc) { + pr_warn("dmatest: No memory for tx %s\n", + dma_chan_name(tx_chan)); + return -ENOMEM; + } + + rx_dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); + if (!rx_dtc) { + pr_warn("dmatest: No memory for rx %s\n", + dma_chan_name(rx_chan)); + return -ENOMEM; + } + + tx_dtc->chan = tx_chan; + rx_dtc->chan = rx_chan; + INIT_LIST_HEAD(&tx_dtc->threads); + INIT_LIST_HEAD(&rx_dtc->threads); + + dmatest_add_slave_threads(tx_dtc, rx_dtc); + thread_count += 1; + + pr_info("dmatest: Started %u threads using %s %s\n", + thread_count, dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + + list_add_tail(&tx_dtc->node, &dmatest_channels); + list_add_tail(&rx_dtc->node, &dmatest_channels); + nr_channels += 2; + + if (iterations) + wait_event(thread_wait, !is_threaded_test_run(tx_dtc, rx_dtc)); + + return 0; +} + +static int xilinx_axidmatest_probe(struct platform_device *pdev) +{ + struct dma_chan *chan, *rx_chan; + int err; + + chan = dma_request_chan(&pdev->dev, "axidma0"); + if (IS_ERR(chan)) { + err = PTR_ERR(chan); + if (err != -EPROBE_DEFER) + pr_err("xilinx_dmatest: No Tx channel\n"); + return err; + } + + rx_chan = dma_request_chan(&pdev->dev, "axidma1"); + if (IS_ERR(rx_chan)) { + err = PTR_ERR(rx_chan); + if (err != -EPROBE_DEFER) + pr_err("xilinx_dmatest: No Rx channel\n"); + goto free_tx; + } + + err = dmatest_add_slave_channels(chan, rx_chan); + if (err) { + pr_err("xilinx_dmatest: Unable to add channels\n"); + goto free_rx; + } + + return 0; + +free_rx: + dma_release_channel(rx_chan); +free_tx: + dma_release_channel(chan); + + return err; +} + +static int xilinx_axidmatest_remove(struct platform_device *pdev) +{ + struct dmatest_chan *dtc, *_dtc; + struct dma_chan *chan; + + list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) { + list_del(&dtc->node); + chan = dtc->chan; + dmatest_cleanup_channel(dtc); + pr_info("xilinx_dmatest: dropped channel %s\n", + dma_chan_name(chan)); + dmaengine_terminate_all(chan); + dma_release_channel(chan); + } + return 0; +} + +static const struct of_device_id xilinx_axidmatest_of_ids[] = { + { .compatible = "xlnx,axi-dma-test-1.00.a",}, + {} +}; + +static struct platform_driver xilinx_axidmatest_driver = { + .driver = { + .name = "xilinx_axidmatest", + .of_match_table = xilinx_axidmatest_of_ids, + }, + .probe = xilinx_axidmatest_probe, + .remove = xilinx_axidmatest_remove, +}; + +static int __init axidma_init(void) +{ + return platform_driver_register(&xilinx_axidmatest_driver); +} +late_initcall(axidma_init); + +static void __exit axidma_exit(void) +{ + platform_driver_unregister(&xilinx_axidmatest_driver); +} +module_exit(axidma_exit) + +MODULE_AUTHOR("Xilinx, Inc."); +MODULE_DESCRIPTION("Xilinx AXI DMA Test Client"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/vdmatest.c +++ linux-xilinx-6.8.0/drivers/dma/xilinx/vdmatest.c @@ -0,0 +1,666 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * XILINX VDMA Engine test client driver + * + * Copyright (C) 2010-2014 Xilinx, Inc. All rights reserved. + * + * Based on Atmel DMA Test Client + * + * Description: + * This is a simple Xilinx VDMA test client for AXI VDMA driver. + * This test assumes both the channels of VDMA are enabled in the + * hardware design and configured in back-to-back connection. Test + * starts by pumping the data onto one channel (MM2S) and then + * compares the data that is received on the other channel (S2MM). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int test_buf_size = 64; +module_param(test_buf_size, uint, 0444); +MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); + +static unsigned int iterations = 1; +module_param(iterations, uint, 0444); +MODULE_PARM_DESC(iterations, + "Iterations before stopping test (default: infinite)"); + +static unsigned int hsize = 64; +module_param(hsize, uint, 0444); +MODULE_PARM_DESC(hsize, "Horizontal size in bytes"); + +static unsigned int vsize = 32; +module_param(vsize, uint, 0444); +MODULE_PARM_DESC(vsize, "Vertical size in bytes"); + +/* + * Initialization patterns. All bytes in the source buffer has bit 7 + * set, all bytes in the destination buffer has bit 7 cleared. + * + * Bit 6 is set for all bytes which are to be copied by the DMA + * engine. Bit 5 is set for all bytes which are to be overwritten by + * the DMA engine. + * + * The remaining bits are the inverse of a counter which increments by + * one for each byte address. + */ +#define PATTERN_SRC 0x80 +#define PATTERN_DST 0x00 +#define PATTERN_COPY 0x40 +#define PATTERN_OVERWRITE 0x20 +#define PATTERN_COUNT_MASK 0x1f + +/* Maximum number of frame buffers */ +#define MAX_NUM_FRAMES 32 + +/** + * struct vdmatest_slave_thread - VDMA test thread + * @node: Thread node + * @task: Task structure pointer + * @tx_chan: Tx channel pointer + * @rx_chan: Rx Channel pointer + * @srcs: Source buffer + * @dsts: Destination buffer + * @type: DMA transaction type + */ +struct xilinx_vdmatest_slave_thread { + struct list_head node; + struct task_struct *task; + struct dma_chan *tx_chan; + struct dma_chan *rx_chan; + u8 **srcs; + u8 **dsts; + enum dma_transaction_type type; + bool done; +}; + +/** + * struct vdmatest_chan - VDMA Test channel + * @node: Channel node + * @chan: DMA channel pointer + * @threads: List of VDMA test threads + */ +struct xilinx_vdmatest_chan { + struct list_head node; + struct dma_chan *chan; + struct list_head threads; +}; + +/* Global variables */ +static DECLARE_WAIT_QUEUE_HEAD(thread_wait); +static LIST_HEAD(xilinx_vdmatest_channels); +static unsigned int nr_channels; +static unsigned int frm_cnt; +static dma_addr_t dma_srcs[MAX_NUM_FRAMES]; +static dma_addr_t dma_dsts[MAX_NUM_FRAMES]; +static struct dma_interleaved_template xt; + +static bool is_threaded_test_run(struct xilinx_vdmatest_chan *tx_dtc, + struct xilinx_vdmatest_chan *rx_dtc) +{ + struct xilinx_vdmatest_slave_thread *thread; + int ret = false; + + list_for_each_entry(thread, &tx_dtc->threads, node) { + if (!thread->done) + ret = true; + } + + list_for_each_entry(thread, &rx_dtc->threads, node) { + if (!thread->done) + ret = true; + } + return ret; +} + +static void xilinx_vdmatest_init_srcs(u8 **bufs, unsigned int start, + unsigned int len) +{ + unsigned int i; + u8 *buf; + + for (; (buf = *bufs); bufs++) { + for (i = 0; i < start; i++) + buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); + for (; i < start + len; i++) + buf[i] = PATTERN_SRC | PATTERN_COPY + | (~i & PATTERN_COUNT_MASK); + for (; i < test_buf_size; i++) + buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK); + buf++; + } +} + +static void xilinx_vdmatest_init_dsts(u8 **bufs, unsigned int start, + unsigned int len) +{ + unsigned int i; + u8 *buf; + + for (; (buf = *bufs); bufs++) { + for (i = 0; i < start; i++) + buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); + for (; i < start + len; i++) + buf[i] = PATTERN_DST | PATTERN_OVERWRITE + | (~i & PATTERN_COUNT_MASK); + for (; i < test_buf_size; i++) + buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK); + } +} + +static void xilinx_vdmatest_mismatch(u8 actual, u8 pattern, unsigned int index, + unsigned int counter, bool is_srcbuf) +{ + u8 diff = actual ^ pattern; + u8 expected = pattern | (~counter & PATTERN_COUNT_MASK); + const char *thread_name = current->comm; + + if (is_srcbuf) + pr_warn( + "%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n", + thread_name, index, expected, actual); + else if ((pattern & PATTERN_COPY) + && (diff & (PATTERN_COPY | PATTERN_OVERWRITE))) + pr_warn( + "%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n", + thread_name, index, expected, actual); + else if (diff & PATTERN_SRC) + pr_warn( + "%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n", + thread_name, index, expected, actual); + else + pr_warn( + "%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n", + thread_name, index, expected, actual); +} + +static unsigned int xilinx_vdmatest_verify(u8 **bufs, unsigned int start, + unsigned int end, unsigned int counter, u8 pattern, + bool is_srcbuf) +{ + unsigned int i, error_count = 0; + u8 actual, expected, *buf; + unsigned int counter_orig = counter; + + for (; (buf = *bufs); bufs++) { + counter = counter_orig; + for (i = start; i < end; i++) { + actual = buf[i]; + expected = pattern | (~counter & PATTERN_COUNT_MASK); + if (actual != expected) { + if (error_count < 32) + xilinx_vdmatest_mismatch(actual, + pattern, i, + counter, is_srcbuf); + error_count++; + } + counter++; + } + } + + if (error_count > 32) + pr_warn("%s: %u errors suppressed\n", + current->comm, error_count - 32); + + return error_count; +} + +static void xilinx_vdmatest_slave_tx_callback(void *completion) +{ + pr_debug("Got tx callback\n"); + complete(completion); +} + +static void xilinx_vdmatest_slave_rx_callback(void *completion) +{ + pr_debug("Got rx callback\n"); + complete(completion); +} + +/* + * Function for slave transfers + * Each thread requires 2 channels, one for transmit, and one for receive + */ +static int xilinx_vdmatest_slave_func(void *data) +{ + struct xilinx_vdmatest_slave_thread *thread = data; + struct dma_chan *tx_chan, *rx_chan; + const char *thread_name; + unsigned int len, error_count; + unsigned int failed_tests = 0, total_tests = 0; + dma_cookie_t tx_cookie = 0, rx_cookie = 0; + enum dma_status status; + enum dma_ctrl_flags flags; + int ret = -ENOMEM, i; + struct xilinx_vdma_config config; + + thread_name = current->comm; + + /* Limit testing scope here */ + test_buf_size = hsize * vsize; + + /* This barrier ensures 'thread' is initialized and + * we get valid DMA channels + */ + smp_rmb(); + tx_chan = thread->tx_chan; + rx_chan = thread->rx_chan; + + thread->srcs = kcalloc(frm_cnt+1, sizeof(u8 *), GFP_KERNEL); + if (!thread->srcs) + goto err_srcs; + for (i = 0; i < frm_cnt; i++) { + thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL); + if (!thread->srcs[i]) + goto err_srcbuf; + } + + thread->dsts = kcalloc(frm_cnt+1, sizeof(u8 *), GFP_KERNEL); + if (!thread->dsts) + goto err_dsts; + for (i = 0; i < frm_cnt; i++) { + thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL); + if (!thread->dsts[i]) + goto err_dstbuf; + } + + set_user_nice(current, 10); + + flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; + + while (!kthread_should_stop() + && !(iterations && total_tests >= iterations)) { + struct dma_device *tx_dev = tx_chan->device; + struct dma_device *rx_dev = rx_chan->device; + struct dma_async_tx_descriptor *txd = NULL; + struct dma_async_tx_descriptor *rxd = NULL; + struct completion rx_cmp, tx_cmp; + unsigned long rx_tmo = + msecs_to_jiffies(30000); /* RX takes longer */ + unsigned long tx_tmo = msecs_to_jiffies(30000); + u8 align = 0; + + total_tests++; + + /* honor larger alignment restrictions */ + align = tx_dev->copy_align; + if (rx_dev->copy_align > align) + align = rx_dev->copy_align; + + if (1 << align > test_buf_size) { + pr_err("%u-byte buffer too small for %d-byte alignment\n", + test_buf_size, 1 << align); + break; + } + + len = test_buf_size; + xilinx_vdmatest_init_srcs(thread->srcs, 0, len); + xilinx_vdmatest_init_dsts(thread->dsts, 0, len); + + /* Zero out configuration */ + memset(&config, 0, sizeof(struct xilinx_vdma_config)); + + /* Set up hardware configuration information */ + config.frm_cnt_en = 1; + config.coalesc = frm_cnt * 10; + config.park = 1; + xilinx_vdma_channel_set_config(tx_chan, &config); + + xilinx_vdma_channel_set_config(rx_chan, &config); + + for (i = 0; i < frm_cnt; i++) { + dma_dsts[i] = dma_map_single(rx_dev->dev, + thread->dsts[i], + test_buf_size, + DMA_FROM_DEVICE); + + if (dma_mapping_error(rx_dev->dev, dma_dsts[i])) { + failed_tests++; + continue; + } + xt.dst_start = dma_dsts[i]; + xt.dir = DMA_DEV_TO_MEM; + xt.numf = vsize; + xt.sgl[0].size = hsize; + xt.sgl[0].icg = 0; + xt.frame_size = 1; + rxd = rx_dev->device_prep_interleaved_dma(rx_chan, + &xt, flags); + rx_cookie = rxd->tx_submit(rxd); + } + + for (i = 0; i < frm_cnt; i++) { + u8 *buf = thread->srcs[i]; + + dma_srcs[i] = dma_map_single(tx_dev->dev, buf, len, + DMA_TO_DEVICE); + + if (dma_mapping_error(tx_dev->dev, dma_srcs[i])) { + failed_tests++; + continue; + } + xt.src_start = dma_srcs[i]; + xt.dir = DMA_MEM_TO_DEV; + xt.numf = vsize; + xt.sgl[0].size = hsize; + xt.sgl[0].icg = 0; + xt.frame_size = 1; + txd = tx_dev->device_prep_interleaved_dma(tx_chan, + &xt, flags); + tx_cookie = txd->tx_submit(txd); + } + + if (!rxd || !txd) { + for (i = 0; i < frm_cnt; i++) + dma_unmap_single(tx_dev->dev, dma_srcs[i], len, + DMA_TO_DEVICE); + for (i = 0; i < frm_cnt; i++) + dma_unmap_single(rx_dev->dev, dma_dsts[i], + test_buf_size, + DMA_FROM_DEVICE); + pr_warn("%s: #%u: prep error with len=0x%x ", + thread_name, total_tests - 1, len); + msleep(100); + failed_tests++; + continue; + } + + init_completion(&rx_cmp); + rxd->callback = xilinx_vdmatest_slave_rx_callback; + rxd->callback_param = &rx_cmp; + + init_completion(&tx_cmp); + txd->callback = xilinx_vdmatest_slave_tx_callback; + txd->callback_param = &tx_cmp; + + if (dma_submit_error(rx_cookie) || + dma_submit_error(tx_cookie)) { + pr_warn("%s: #%u: submit error %d/%d with len=0x%x ", + thread_name, total_tests - 1, + rx_cookie, tx_cookie, len); + msleep(100); + failed_tests++; + continue; + } + dma_async_issue_pending(tx_chan); + dma_async_issue_pending(rx_chan); + + tx_tmo = wait_for_completion_timeout(&tx_cmp, tx_tmo); + + status = dma_async_is_tx_complete(tx_chan, tx_cookie, + NULL, NULL); + + if (tx_tmo == 0) { + pr_warn("%s: #%u: tx test timed out\n", + thread_name, total_tests - 1); + failed_tests++; + continue; + } else if (status != DMA_COMPLETE) { + pr_warn( + "%s: #%u: tx got completion callback, ", + thread_name, total_tests - 1); + pr_warn("but status is \'%s\'\n", + status == DMA_ERROR ? "error" : + "in progress"); + failed_tests++; + continue; + } + + rx_tmo = wait_for_completion_timeout(&rx_cmp, rx_tmo); + status = dma_async_is_tx_complete(rx_chan, rx_cookie, + NULL, NULL); + + if (rx_tmo == 0) { + pr_warn("%s: #%u: rx test timed out\n", + thread_name, total_tests - 1); + failed_tests++; + continue; + } else if (status != DMA_COMPLETE) { + pr_warn( + "%s: #%u: rx got completion callback, ", + thread_name, total_tests - 1); + pr_warn("but status is \'%s\'\n", + status == DMA_ERROR ? "error" : + "in progress"); + failed_tests++; + continue; + } + + /* Unmap by myself */ + for (i = 0; i < frm_cnt; i++) + dma_unmap_single(rx_dev->dev, dma_dsts[i], + test_buf_size, DMA_FROM_DEVICE); + + error_count = 0; + + pr_debug("%s: verifying source buffer...\n", thread_name); + error_count += xilinx_vdmatest_verify(thread->srcs, 0, 0, + 0, PATTERN_SRC, true); + error_count += xilinx_vdmatest_verify(thread->srcs, 0, + len, 0, PATTERN_SRC | PATTERN_COPY, true); + error_count += xilinx_vdmatest_verify(thread->srcs, len, + test_buf_size, len, PATTERN_SRC, true); + + pr_debug("%s: verifying dest buffer...\n", + thread->task->comm); + error_count += xilinx_vdmatest_verify(thread->dsts, 0, 0, + 0, PATTERN_DST, false); + error_count += xilinx_vdmatest_verify(thread->dsts, 0, + len, 0, PATTERN_SRC | PATTERN_COPY, false); + error_count += xilinx_vdmatest_verify(thread->dsts, len, + test_buf_size, len, PATTERN_DST, false); + + if (error_count) { + pr_warn("%s: #%u: %u errors with len=0x%x\n", + thread_name, total_tests - 1, error_count, len); + failed_tests++; + } else { + pr_debug("%s: #%u: No errors with len=0x%x\n", + thread_name, total_tests - 1, len); + } + } + + ret = 0; + for (i = 0; thread->dsts[i]; i++) + kfree(thread->dsts[i]); +err_dstbuf: + kfree(thread->dsts); +err_dsts: + for (i = 0; thread->srcs[i]; i++) + kfree(thread->srcs[i]); +err_srcbuf: + kfree(thread->srcs); +err_srcs: + pr_notice("%s: terminating after %u tests, %u failures (status %d)\n", + thread_name, total_tests, failed_tests, ret); + + thread->done = true; + wake_up(&thread_wait); + + return ret; +} + +static void xilinx_vdmatest_cleanup_channel(struct xilinx_vdmatest_chan *dtc) +{ + struct xilinx_vdmatest_slave_thread *thread, *_thread; + int ret; + + list_for_each_entry_safe(thread, _thread, + &dtc->threads, node) { + ret = kthread_stop(thread->task); + pr_info("xilinx_vdmatest: thread %s exited with status %d\n", + thread->task->comm, ret); + list_del(&thread->node); + put_task_struct(thread->task); + kfree(thread); + } + kfree(dtc); +} + +static int +xilinx_vdmatest_add_slave_threads(struct xilinx_vdmatest_chan *tx_dtc, + struct xilinx_vdmatest_chan *rx_dtc) +{ + struct xilinx_vdmatest_slave_thread *thread; + struct dma_chan *tx_chan = tx_dtc->chan; + struct dma_chan *rx_chan = rx_dtc->chan; + + thread = kzalloc(sizeof(struct xilinx_vdmatest_slave_thread), + GFP_KERNEL); + if (!thread) + pr_warn("xilinx_vdmatest: No memory for slave thread %s-%s\n", + dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + + thread->tx_chan = tx_chan; + thread->rx_chan = rx_chan; + thread->type = (enum dma_transaction_type)DMA_SLAVE; + + /* This barrier ensures the DMA channels in the 'thread' + * are initialized + */ + smp_wmb(); + thread->task = kthread_run(xilinx_vdmatest_slave_func, thread, "%s-%s", + dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + if (IS_ERR(thread->task)) { + pr_warn("xilinx_vdmatest: Failed to run thread %s-%s\n", + dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + kfree(thread); + return PTR_ERR(thread->task); + } + + get_task_struct(thread->task); + list_add_tail(&thread->node, &tx_dtc->threads); + + /* Added one thread with 2 channels */ + return 1; +} + +static int xilinx_vdmatest_add_slave_channels(struct dma_chan *tx_chan, + struct dma_chan *rx_chan) +{ + struct xilinx_vdmatest_chan *tx_dtc, *rx_dtc; + unsigned int thread_count = 0; + + tx_dtc = kmalloc(sizeof(struct xilinx_vdmatest_chan), GFP_KERNEL); + if (!tx_dtc) + return -ENOMEM; + + rx_dtc = kmalloc(sizeof(struct xilinx_vdmatest_chan), GFP_KERNEL); + if (!rx_dtc) + return -ENOMEM; + + tx_dtc->chan = tx_chan; + rx_dtc->chan = rx_chan; + INIT_LIST_HEAD(&tx_dtc->threads); + INIT_LIST_HEAD(&rx_dtc->threads); + + xilinx_vdmatest_add_slave_threads(tx_dtc, rx_dtc); + thread_count += 1; + + pr_info("xilinx_vdmatest: Started %u threads using %s %s\n", + thread_count, dma_chan_name(tx_chan), dma_chan_name(rx_chan)); + + list_add_tail(&tx_dtc->node, &xilinx_vdmatest_channels); + list_add_tail(&rx_dtc->node, &xilinx_vdmatest_channels); + nr_channels += 2; + + if (iterations) + wait_event(thread_wait, !is_threaded_test_run(tx_dtc, rx_dtc)); + + return 0; +} + +static int xilinx_vdmatest_probe(struct platform_device *pdev) +{ + struct dma_chan *chan, *rx_chan; + int err; + + err = of_property_read_u32(pdev->dev.of_node, + "xlnx,num-fstores", &frm_cnt); + if (err < 0) { + pr_err("xilinx_vdmatest: missing xlnx,num-fstores property\n"); + return err; + } + + chan = dma_request_chan(&pdev->dev, "vdma0"); + if (IS_ERR(chan)) { + err = PTR_ERR(chan); + if (err != -EPROBE_DEFER) + pr_err("xilinx_vdmatest: No Tx channel\n"); + return err; + } + + rx_chan = dma_request_chan(&pdev->dev, "vdma1"); + if (IS_ERR(rx_chan)) { + err = PTR_ERR(rx_chan); + if (err != -EPROBE_DEFER) + pr_err("xilinx_vdmatest: No Rx channel\n"); + goto free_tx; + } + + err = xilinx_vdmatest_add_slave_channels(chan, rx_chan); + if (err) { + pr_err("xilinx_vdmatest: Unable to add channels\n"); + goto free_rx; + } + return 0; + +free_rx: + dma_release_channel(rx_chan); +free_tx: + dma_release_channel(chan); + + return err; +} + +static int xilinx_vdmatest_remove(struct platform_device *pdev) +{ + struct xilinx_vdmatest_chan *dtc, *_dtc; + struct dma_chan *chan; + + list_for_each_entry_safe(dtc, _dtc, &xilinx_vdmatest_channels, node) { + list_del(&dtc->node); + chan = dtc->chan; + xilinx_vdmatest_cleanup_channel(dtc); + pr_info("xilinx_vdmatest: dropped channel %s\n", + dma_chan_name(chan)); + dmaengine_terminate_async(chan); + dma_release_channel(chan); + } + return 0; +} + +static const struct of_device_id xilinx_vdmatest_of_ids[] = { + { .compatible = "xlnx,axi-vdma-test-1.00.a",}, + {} +}; + +static struct platform_driver xilinx_vdmatest_driver = { + .driver = { + .name = "xilinx_vdmatest", + .owner = THIS_MODULE, + .of_match_table = xilinx_vdmatest_of_ids, + }, + .probe = xilinx_vdmatest_probe, + .remove = xilinx_vdmatest_remove, +}; + +module_platform_driver(xilinx_vdmatest_driver); + +MODULE_AUTHOR("Xilinx, Inc."); +MODULE_DESCRIPTION("Xilinx AXI VDMA Test Client"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/xdma-regs.h +++ linux-xilinx-6.8.0/drivers/dma/xilinx/xdma-regs.h @@ -117,6 +117,9 @@ CHAN_CTRL_IE_WRITE_ERROR | \ CHAN_CTRL_IE_DESC_ERROR) +/* bits of the channel status register */ +#define XDMA_CHAN_STATUS_BUSY BIT(0) + #define XDMA_CHAN_STATUS_MASK CHAN_CTRL_START #define XDMA_CHAN_ERROR_MASK (CHAN_CTRL_IE_DESC_ALIGN_MISMATCH | \ --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/xdma.c +++ linux-xilinx-6.8.0/drivers/dma/xilinx/xdma.c @@ -71,6 +71,8 @@ enum dma_transfer_direction dir; struct dma_slave_config cfg; u32 irq; + struct completion last_interrupt; + bool stop_requested; }; /** @@ -376,6 +378,8 @@ return ret; xchan->busy = true; + xchan->stop_requested = false; + reinit_completion(&xchan->last_interrupt); return 0; } @@ -387,7 +391,6 @@ static int xdma_xfer_stop(struct xdma_chan *xchan) { int ret; - u32 val; struct xdma_device *xdev = xchan->xdev_hdl; /* clear run stop bit to prevent any further auto-triggering */ @@ -395,13 +398,7 @@ CHAN_CTRL_RUN_STOP); if (ret) return ret; - - /* Clear the channel status register */ - ret = regmap_read(xdev->rmap, xchan->base + XDMA_CHAN_STATUS_RC, &val); - if (ret) - return ret; - - return 0; + return ret; } /** @@ -474,6 +471,8 @@ xchan->xdev_hdl = xdev; xchan->base = base + i * XDMA_CHAN_STRIDE; xchan->dir = dir; + xchan->stop_requested = false; + init_completion(&xchan->last_interrupt); ret = xdma_channel_init(xchan); if (ret) @@ -521,6 +520,7 @@ spin_lock_irqsave(&xdma_chan->vchan.lock, flags); xdma_chan->busy = false; + xdma_chan->stop_requested = true; vd = vchan_next_desc(&xdma_chan->vchan); if (vd) { list_del(&vd->node); @@ -542,17 +542,26 @@ static void xdma_synchronize(struct dma_chan *chan) { struct xdma_chan *xdma_chan = to_xdma_chan(chan); + struct xdma_device *xdev = xdma_chan->xdev_hdl; + int st = 0; + + /* If the engine continues running, wait for the last interrupt */ + regmap_read(xdev->rmap, xdma_chan->base + XDMA_CHAN_STATUS, &st); + if (st & XDMA_CHAN_STATUS_BUSY) + wait_for_completion_timeout(&xdma_chan->last_interrupt, msecs_to_jiffies(1000)); vchan_synchronize(&xdma_chan->vchan); } /** - * xdma_fill_descs - Fill hardware descriptors with contiguous memory block addresses - * @sw_desc: tx descriptor state container - * @src_addr: Value for a ->src_addr field of a first descriptor - * @dst_addr: Value for a ->dst_addr field of a first descriptor - * @size: Total size of a contiguous memory block - * @filled_descs_num: Number of filled hardware descriptors for corresponding sw_desc + * xdma_fill_descs() - Fill hardware descriptors for one contiguous memory chunk. + * More than one descriptor will be used if the size is bigger + * than XDMA_DESC_BLEN_MAX. + * @sw_desc: Descriptor container + * @src_addr: First value for the ->src_addr field + * @dst_addr: First value for the ->dst_addr field + * @size: Size of the contiguous memory block + * @filled_descs_num: Index of the first descriptor to take care of in @sw_desc */ static inline u32 xdma_fill_descs(struct xdma_desc *sw_desc, u64 src_addr, u64 dst_addr, u32 size, u32 filled_descs_num) @@ -704,7 +713,7 @@ desc_num = 0; for (i = 0; i < periods; i++) { desc_num += xdma_fill_descs(sw_desc, *src, *dst, period_size, desc_num); - addr += i * period_size; + addr += period_size; } tx_desc = vchan_tx_prep(&xdma_chan->vchan, &sw_desc->vdesc, flags); @@ -878,6 +887,9 @@ spin_lock(&xchan->vchan.lock); + if (xchan->stop_requested) + complete(&xchan->last_interrupt); + /* get submitted request */ vd = vchan_next_desc(&xchan->vchan); if (!vd) --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/xilinx_dpdma.c +++ linux-xilinx-6.8.0/drivers/dma/xilinx/xilinx_dpdma.c @@ -214,7 +214,8 @@ * @running: true if the channel is running * @first_frame: flag for the first frame of stream * @video_group: flag if multi-channel operation is needed for video channels - * @lock: lock to access struct xilinx_dpdma_chan + * @lock: lock to access struct xilinx_dpdma_chan. Must be taken before + * @vchan.lock, if both are to be held. * @desc_pool: descriptor allocation pool * @err_task: error IRQ bottom half handler * @desc: References to descriptors being processed @@ -670,6 +671,84 @@ } /** + * xilinx_dpdma_chan_prep_cyclic - Prepare a cyclic dma descriptor + * @chan: DPDMA channel + * @buf_addr: buffer address + * @buf_len: buffer length + * @period_len: number of periods + * @flags: tx flags argument passed in to prepare function + * + * Prepare a tx descriptor incudling internal software/hardware descriptors + * for the given cyclic transaction. + * + * Return: A dma async tx descriptor on success, or NULL. + */ +static struct dma_async_tx_descriptor * +xilinx_dpdma_chan_prep_cyclic(struct xilinx_dpdma_chan *chan, + dma_addr_t buf_addr, size_t buf_len, + size_t period_len, unsigned long flags) +{ + struct xilinx_dpdma_tx_desc *tx_desc; + struct xilinx_dpdma_sw_desc *sw_desc, *last = NULL; + unsigned int periods = buf_len / period_len; + unsigned int i; + + tx_desc = xilinx_dpdma_chan_alloc_tx_desc(chan); + if (!tx_desc) + return (void *)tx_desc; + + for (i = 0; i < periods; i++) { + struct xilinx_dpdma_hw_desc *hw_desc; + + if (!IS_ALIGNED(buf_addr, XILINX_DPDMA_ALIGN_BYTES)) { + dev_err(chan->xdev->dev, + "buffer should be aligned at %d B\n", + XILINX_DPDMA_ALIGN_BYTES); + goto error; + } + + sw_desc = xilinx_dpdma_chan_alloc_sw_desc(chan); + if (!sw_desc) + goto error; + + xilinx_dpdma_sw_desc_set_dma_addrs(chan->xdev, sw_desc, last, + &buf_addr, 1); + hw_desc = &sw_desc->hw; + hw_desc->xfer_size = period_len; + hw_desc->hsize_stride = + FIELD_PREP(XILINX_DPDMA_DESC_HSIZE_STRIDE_HSIZE_MASK, + period_len) | + FIELD_PREP(XILINX_DPDMA_DESC_HSIZE_STRIDE_STRIDE_MASK, + period_len); + hw_desc->control |= XILINX_DPDMA_DESC_CONTROL_PREEMBLE; + hw_desc->control |= XILINX_DPDMA_DESC_CONTROL_IGNORE_DONE; + hw_desc->control |= XILINX_DPDMA_DESC_CONTROL_COMPLETE_INTR; + + list_add_tail(&sw_desc->node, &tx_desc->descriptors); + + buf_addr += period_len; + last = sw_desc; + } + + sw_desc = list_first_entry(&tx_desc->descriptors, + struct xilinx_dpdma_sw_desc, node); + last->hw.next_desc = lower_32_bits(sw_desc->dma_addr); + if (chan->xdev->ext_addr) + last->hw.addr_ext |= + FIELD_PREP(XILINX_DPDMA_DESC_ADDR_EXT_NEXT_ADDR_MASK, + upper_32_bits(sw_desc->dma_addr)); + + last->hw.control |= XILINX_DPDMA_DESC_CONTROL_LAST_OF_FRAME; + + return vchan_tx_prep(&chan->vchan, &tx_desc->vdesc, flags); + +error: + xilinx_dpdma_chan_free_tx_desc(&tx_desc->vdesc); + + return NULL; +} + +/** * xilinx_dpdma_chan_prep_interleaved_dma - Prepare an interleaved dma * descriptor * @chan: DPDMA channel @@ -1097,12 +1176,14 @@ * Complete the active descriptor, if any, promote the pending * descriptor to active, and queue the next transfer, if any. */ + spin_lock(&chan->vchan.lock); if (chan->desc.active) vchan_cookie_complete(&chan->desc.active->vdesc); chan->desc.active = pending; chan->desc.pending = NULL; xilinx_dpdma_chan_queue_transfer(chan); + spin_unlock(&chan->vchan.lock); out: spin_unlock_irqrestore(&chan->lock, flags); @@ -1188,6 +1269,23 @@ /* ----------------------------------------------------------------------------- * DMA Engine Operations */ +static struct dma_async_tx_descriptor * +xilinx_dpdma_prep_dma_cyclic(struct dma_chan *dchan, dma_addr_t buf_addr, + size_t buf_len, size_t period_len, + enum dma_transfer_direction direction, + unsigned long flags) +{ + struct xilinx_dpdma_chan *chan = to_xilinx_chan(dchan); + + if (direction != DMA_MEM_TO_DEV) + return NULL; + + if (buf_len % period_len) + return NULL; + + return xilinx_dpdma_chan_prep_cyclic(chan, buf_addr, buf_len, + period_len, flags); +} static struct dma_async_tx_descriptor * xilinx_dpdma_prep_interleaved_dma(struct dma_chan *dchan, @@ -1264,10 +1362,12 @@ struct xilinx_dpdma_chan *chan = to_xilinx_chan(dchan); unsigned long flags; - spin_lock_irqsave(&chan->vchan.lock, flags); + spin_lock_irqsave(&chan->lock, flags); + spin_lock(&chan->vchan.lock); if (vchan_issue_pending(&chan->vchan)) xilinx_dpdma_chan_queue_transfer(chan); - spin_unlock_irqrestore(&chan->vchan.lock, flags); + spin_unlock(&chan->vchan.lock); + spin_unlock_irqrestore(&chan->lock, flags); } static int xilinx_dpdma_config(struct dma_chan *dchan, @@ -1495,7 +1595,9 @@ XILINX_DPDMA_EINTR_CHAN_ERR_MASK << chan->id); spin_lock_irqsave(&chan->lock, flags); + spin_lock(&chan->vchan.lock); xilinx_dpdma_chan_queue_transfer(chan); + spin_unlock(&chan->vchan.lock); spin_unlock_irqrestore(&chan->lock, flags); } @@ -1667,6 +1769,7 @@ dma_cap_set(DMA_SLAVE, ddev->cap_mask); dma_cap_set(DMA_PRIVATE, ddev->cap_mask); + dma_cap_set(DMA_CYCLIC, ddev->cap_mask); dma_cap_set(DMA_INTERLEAVE, ddev->cap_mask); dma_cap_set(DMA_REPEAT, ddev->cap_mask); dma_cap_set(DMA_LOAD_EOT, ddev->cap_mask); @@ -1674,6 +1777,7 @@ ddev->device_alloc_chan_resources = xilinx_dpdma_alloc_chan_resources; ddev->device_free_chan_resources = xilinx_dpdma_free_chan_resources; + ddev->device_prep_dma_cyclic = xilinx_dpdma_prep_dma_cyclic; ddev->device_prep_interleaved_dma = xilinx_dpdma_prep_interleaved_dma; /* TODO: Can we achieve better granularity ? */ ddev->device_tx_status = dma_cookie_status; --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/xilinx_frmbuf.c +++ linux-xilinx-6.8.0/drivers/dma/xilinx/xilinx_frmbuf.c @@ -0,0 +1,1903 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * DMAEngine driver for Xilinx Framebuffer IP + * + * Copyright (C) 2016 - 2021 Xilinx, Inc. + * + * Authors: Radhey Shyam Pandey + * John Nichols + * Jeffrey Mouroux + * + * Based on the Freescale DMA driver. + * + * Description: + * The AXI Framebuffer core is a soft Xilinx IP core that + * provides high-bandwidth direct memory access between memory + * and AXI4-Stream. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../dmaengine.h" + +/* Register/Descriptor Offsets */ +#define XILINX_FRMBUF_CTRL_OFFSET 0x00 +#define XILINX_FRMBUF_GIE_OFFSET 0x04 +#define XILINX_FRMBUF_IE_OFFSET 0x08 +#define XILINX_FRMBUF_ISR_OFFSET 0x0c +#define XILINX_FRMBUF_WIDTH_OFFSET 0x10 +#define XILINX_FRMBUF_HEIGHT_OFFSET 0x18 +#define XILINX_FRMBUF_STRIDE_OFFSET 0x20 +#define XILINX_FRMBUF_FMT_OFFSET 0x28 +#define XILINX_FRMBUF_ADDR_OFFSET 0x30 +#define XILINX_FRMBUF_ADDR2_OFFSET 0x3c +#define XILINX_FRMBUF_FID_OFFSET 0x48 +#define XILINX_FRMBUF_FID_MODE_OFFSET 0x50 +#define XILINX_FRMBUF_ADDR3_OFFSET 0x54 +#define XILINX_FRMBUF_FID_ERR_OFFSET 0x58 +#define XILINX_FRMBUF_FID_OUT_OFFSET 0x60 +#define XILINX_FRMBUF_RD_ADDR3_OFFSET 0x74 + +/* Control Registers */ +#define XILINX_FRMBUF_CTRL_AP_START BIT(0) +#define XILINX_FRMBUF_CTRL_AP_DONE BIT(1) +#define XILINX_FRMBUF_CTRL_AP_IDLE BIT(2) +#define XILINX_FRMBUF_CTRL_AP_READY BIT(3) +#define XILINX_FRMBUF_CTRL_FLUSH BIT(5) +#define XILINX_FRMBUF_CTRL_FLUSH_DONE BIT(6) +#define XILINX_FRMBUF_CTRL_AUTO_RESTART BIT(7) +#define XILINX_FRMBUF_GIE_EN BIT(0) + +/* Interrupt Status and Control */ +#define XILINX_FRMBUF_IE_AP_DONE BIT(0) +#define XILINX_FRMBUF_IE_AP_READY BIT(1) + +#define XILINX_FRMBUF_ISR_AP_DONE_IRQ BIT(0) +#define XILINX_FRMBUF_ISR_AP_READY_IRQ BIT(1) + +#define XILINX_FRMBUF_ISR_ALL_IRQ_MASK \ + (XILINX_FRMBUF_ISR_AP_DONE_IRQ | \ + XILINX_FRMBUF_ISR_AP_READY_IRQ) + +/* Video Format Register Settings */ +#define XILINX_FRMBUF_FMT_RGBX8 10 +#define XILINX_FRMBUF_FMT_YUVX8 11 +#define XILINX_FRMBUF_FMT_YUYV8 12 +#define XILINX_FRMBUF_FMT_RGBA8 13 +#define XILINX_FRMBUF_FMT_YUVA8 14 +#define XILINX_FRMBUF_FMT_RGBX10 15 +#define XILINX_FRMBUF_FMT_YUVX10 16 +#define XILINX_FRMBUF_FMT_Y_UV8 18 +#define XILINX_FRMBUF_FMT_Y_UV8_420 19 +#define XILINX_FRMBUF_FMT_RGB8 20 +#define XILINX_FRMBUF_FMT_YUV8 21 +#define XILINX_FRMBUF_FMT_Y_UV10 22 +#define XILINX_FRMBUF_FMT_Y_UV10_420 23 +#define XILINX_FRMBUF_FMT_Y8 24 +#define XILINX_FRMBUF_FMT_Y10 25 +#define XILINX_FRMBUF_FMT_BGRA8 26 +#define XILINX_FRMBUF_FMT_BGRX8 27 +#define XILINX_FRMBUF_FMT_UYVY8 28 +#define XILINX_FRMBUF_FMT_BGR8 29 +#define XILINX_FRMBUF_FMT_RGBX12 30 +#define XILINX_FRMBUF_FMT_RGB16 35 +#define XILINX_FRMBUF_FMT_Y_U_V8 42 +#define XILINX_FRMBUF_FMT_Y_U_V10 43 + +/* FID Register */ +#define XILINX_FRMBUF_FID_MASK BIT(0) + +/* FID ERR Register */ +#define XILINX_FRMBUF_FID_ERR_MASK BIT(0) +#define XILINX_FRMBUF_FID_OUT_MASK BIT(0) + +#define XILINX_FRMBUF_ALIGN_MUL 8 + +#define WAIT_FOR_FLUSH_DONE 25 + +/* Pixels per clock property flag */ +#define XILINX_PPC_PROP BIT(0) +#define XILINX_FLUSH_PROP BIT(1) +#define XILINX_FID_PROP BIT(2) +#define XILINX_CLK_PROP BIT(3) +#define XILINX_THREE_PLANES_PROP BIT(4) +#define XILINX_FID_ERR_DETECT_PROP BIT(5) + +#define XILINX_FRMBUF_MIN_HEIGHT (64) +#define XILINX_FRMBUF_MIN_WIDTH (64) + +/** + * struct xilinx_frmbuf_desc_hw - Hardware Descriptor + * @luma_plane_addr: Luma or packed plane buffer address + * @chroma_plane_addr: Chroma plane buffer address + * @vsize: Vertical Size + * @hsize: Horizontal Size + * @stride: Number of bytes between the first + * pixels of each horizontal line + */ +struct xilinx_frmbuf_desc_hw { + dma_addr_t luma_plane_addr; + dma_addr_t chroma_plane_addr[2]; + u32 vsize; + u32 hsize; + u32 stride; +}; + +/** + * struct xilinx_frmbuf_tx_descriptor - Per Transaction structure + * @async_tx: Async transaction descriptor + * @hw: Hardware descriptor + * @node: Node in the channel descriptors list + * @fid: Field ID of buffer + * @earlycb: Whether the callback should be called when in staged state + */ +struct xilinx_frmbuf_tx_descriptor { + struct dma_async_tx_descriptor async_tx; + struct xilinx_frmbuf_desc_hw hw; + struct list_head node; + u32 fid; + u32 earlycb; +}; + +/** + * struct xilinx_frmbuf_chan - Driver specific dma channel structure + * @xdev: Driver specific device structure + * @lock: Descriptor operation lock + * @chan_node: Member of a list of framebuffer channel instances + * @pending_list: Descriptors waiting + * @done_list: Complete descriptors + * @staged_desc: Next buffer to be programmed + * @active_desc: Currently active buffer being read/written to + * @common: DMA common channel + * @dev: The dma device + * @write_addr: callback that will write dma addresses to IP (32 or 64 bit) + * @irq: Channel IRQ + * @direction: Transfer direction + * @idle: Channel idle state + * @tasklet: Cleanup work after irq + * @vid_fmt: Reference to currently assigned video format description + * @hw_fid: FID enabled in hardware flag + * @mode: Select operation mode + * @fid_err_flag: Field id error detection flag + * @fid_out_val: Field id out val + * @fid_mode: Select fid mode + */ +struct xilinx_frmbuf_chan { + struct xilinx_frmbuf_device *xdev; + /* Descriptor operation lock */ + spinlock_t lock; + struct list_head chan_node; + struct list_head pending_list; + struct list_head done_list; + struct xilinx_frmbuf_tx_descriptor *staged_desc; + struct xilinx_frmbuf_tx_descriptor *active_desc; + struct dma_chan common; + struct device *dev; + void (*write_addr)(struct xilinx_frmbuf_chan *chan, u32 reg, + dma_addr_t value); + int irq; + enum dma_transfer_direction direction; + bool idle; + struct tasklet_struct tasklet; + const struct xilinx_frmbuf_format_desc *vid_fmt; + bool hw_fid; + enum operation_mode mode; + u8 fid_err_flag; + u8 fid_out_val; + enum fid_modes fid_mode; +}; + +/** + * struct xilinx_frmbuf_format_desc - lookup table to match fourcc to format + * @dts_name: Device tree name for this entry. + * @id: Format ID + * @bpw: Bits of pixel data + padding in a 32-bit word (luma plane for semi-pl) + * @ppw: Number of pixels represented in a 32-bit word (luma plane for semi-pl) + * @num_planes: Expected number of plane buffers in framebuffer for this format + * @drm_fmt: DRM video framework equivalent fourcc code + * @v4l2_fmt: Video 4 Linux framework equivalent fourcc code + * @fmt_bitmask: Flag identifying this format in device-specific "enabled" + * bitmap + */ +struct xilinx_frmbuf_format_desc { + const char *dts_name; + u32 id; + u32 bpw; + u32 ppw; + u32 num_planes; + u32 drm_fmt; + u32 v4l2_fmt; + u32 fmt_bitmask; +}; + +static LIST_HEAD(frmbuf_chan_list); +static DEFINE_MUTEX(frmbuf_chan_list_lock); + +static const struct xilinx_frmbuf_format_desc xilinx_frmbuf_formats[] = { + { + .dts_name = "xbgr8888", + .id = XILINX_FRMBUF_FMT_RGBX8, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_XBGR8888, + .v4l2_fmt = V4L2_PIX_FMT_BGRX32, + .fmt_bitmask = BIT(0), + }, + { + .dts_name = "xbgr2101010", + .id = XILINX_FRMBUF_FMT_RGBX10, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_XBGR2101010, + .v4l2_fmt = V4L2_PIX_FMT_XBGR30, + .fmt_bitmask = BIT(1), + }, + { + .dts_name = "xrgb8888", + .id = XILINX_FRMBUF_FMT_BGRX8, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_XRGB8888, + .v4l2_fmt = V4L2_PIX_FMT_XBGR32, + .fmt_bitmask = BIT(2), + }, + { + .dts_name = "xvuy8888", + .id = XILINX_FRMBUF_FMT_YUVX8, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_XVUY8888, + .v4l2_fmt = V4L2_PIX_FMT_XVUY32, + .fmt_bitmask = BIT(5), + }, + { + .dts_name = "vuy888", + .id = XILINX_FRMBUF_FMT_YUV8, + .bpw = 24, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_VUY888, + .v4l2_fmt = V4L2_PIX_FMT_VUY24, + .fmt_bitmask = BIT(6), + }, + { + .dts_name = "yuvx2101010", + .id = XILINX_FRMBUF_FMT_YUVX10, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_XVUY2101010, + .v4l2_fmt = V4L2_PIX_FMT_XVUY10, + .fmt_bitmask = BIT(7), + }, + { + .dts_name = "yuyv", + .id = XILINX_FRMBUF_FMT_YUYV8, + .bpw = 32, + .ppw = 2, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_YUYV, + .v4l2_fmt = V4L2_PIX_FMT_YUYV, + .fmt_bitmask = BIT(8), + }, + { + .dts_name = "uyvy", + .id = XILINX_FRMBUF_FMT_UYVY8, + .bpw = 32, + .ppw = 2, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_UYVY, + .v4l2_fmt = V4L2_PIX_FMT_UYVY, + .fmt_bitmask = BIT(9), + }, + { + .dts_name = "nv16", + .id = XILINX_FRMBUF_FMT_Y_UV8, + .bpw = 32, + .ppw = 4, + .num_planes = 2, + .drm_fmt = DRM_FORMAT_NV16, + .v4l2_fmt = V4L2_PIX_FMT_NV16M, + .fmt_bitmask = BIT(11), + }, + { + .dts_name = "nv16", + .id = XILINX_FRMBUF_FMT_Y_UV8, + .bpw = 32, + .ppw = 4, + .num_planes = 2, + .drm_fmt = 0, + .v4l2_fmt = V4L2_PIX_FMT_NV16, + .fmt_bitmask = BIT(11), + }, + { + .dts_name = "nv12", + .id = XILINX_FRMBUF_FMT_Y_UV8_420, + .bpw = 32, + .ppw = 4, + .num_planes = 2, + .drm_fmt = DRM_FORMAT_NV12, + .v4l2_fmt = V4L2_PIX_FMT_NV12M, + .fmt_bitmask = BIT(12), + }, + { + .dts_name = "nv12", + .id = XILINX_FRMBUF_FMT_Y_UV8_420, + .bpw = 32, + .ppw = 4, + .num_planes = 2, + .drm_fmt = 0, + .v4l2_fmt = V4L2_PIX_FMT_NV12, + .fmt_bitmask = BIT(12), + }, + { + .dts_name = "xv15", + .id = XILINX_FRMBUF_FMT_Y_UV10_420, + .bpw = 32, + .ppw = 3, + .num_planes = 2, + .drm_fmt = DRM_FORMAT_XV15, + .v4l2_fmt = V4L2_PIX_FMT_XV15M, + .fmt_bitmask = BIT(13), + }, + { + .dts_name = "xv15", + .id = XILINX_FRMBUF_FMT_Y_UV10_420, + .bpw = 32, + .ppw = 3, + .num_planes = 2, + .drm_fmt = 0, + .v4l2_fmt = V4L2_PIX_FMT_XV15, + .fmt_bitmask = BIT(13), + }, + { + .dts_name = "xv20", + .id = XILINX_FRMBUF_FMT_Y_UV10, + .bpw = 32, + .ppw = 3, + .num_planes = 2, + .drm_fmt = DRM_FORMAT_XV20, + .v4l2_fmt = V4L2_PIX_FMT_XV20M, + .fmt_bitmask = BIT(14), + }, + { + .dts_name = "xv20", + .id = XILINX_FRMBUF_FMT_Y_UV10, + .bpw = 32, + .ppw = 3, + .num_planes = 2, + .drm_fmt = 0, + .v4l2_fmt = V4L2_PIX_FMT_XV20, + .fmt_bitmask = BIT(14), + }, + { + .dts_name = "bgr888", + .id = XILINX_FRMBUF_FMT_RGB8, + .bpw = 24, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_BGR888, + .v4l2_fmt = V4L2_PIX_FMT_RGB24, + .fmt_bitmask = BIT(15), + }, + { + .dts_name = "y8", + .id = XILINX_FRMBUF_FMT_Y8, + .bpw = 32, + .ppw = 4, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_Y8, + .v4l2_fmt = V4L2_PIX_FMT_GREY, + .fmt_bitmask = BIT(16), + }, + { + .dts_name = "y10", + .id = XILINX_FRMBUF_FMT_Y10, + .bpw = 32, + .ppw = 3, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_Y10, + .v4l2_fmt = V4L2_PIX_FMT_XY10, + .fmt_bitmask = BIT(17), + }, + { + .dts_name = "rgb888", + .id = XILINX_FRMBUF_FMT_BGR8, + .bpw = 24, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_RGB888, + .v4l2_fmt = V4L2_PIX_FMT_BGR24, + .fmt_bitmask = BIT(18), + }, + { + .dts_name = "abgr8888", + .id = XILINX_FRMBUF_FMT_RGBA8, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_ABGR8888, + .v4l2_fmt = 0, + .fmt_bitmask = BIT(19), + }, + { + .dts_name = "argb8888", + .id = XILINX_FRMBUF_FMT_BGRA8, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_ARGB8888, + .v4l2_fmt = 0, + .fmt_bitmask = BIT(20), + }, + { + .dts_name = "avuy8888", + .id = XILINX_FRMBUF_FMT_YUVA8, + .bpw = 32, + .ppw = 1, + .num_planes = 1, + .drm_fmt = DRM_FORMAT_AVUY, + .v4l2_fmt = 0, + .fmt_bitmask = BIT(21), + }, + { + .dts_name = "xbgr4121212", + .id = XILINX_FRMBUF_FMT_RGBX12, + .bpw = 40, + .ppw = 1, + .num_planes = 1, + .v4l2_fmt = V4L2_PIX_FMT_XBGR40, + .fmt_bitmask = BIT(22), + }, + { + .dts_name = "rgb16", + .id = XILINX_FRMBUF_FMT_RGB16, + .bpw = 48, + .ppw = 1, + .num_planes = 1, + .v4l2_fmt = V4L2_PIX_FMT_BGR48, + .fmt_bitmask = BIT(23), + }, + { + .dts_name = "y_u_v8", + .id = XILINX_FRMBUF_FMT_Y_U_V8, + .bpw = 32, + .ppw = 4, + .num_planes = 3, + .v4l2_fmt = V4L2_PIX_FMT_YUV444M, + .drm_fmt = DRM_FORMAT_YUV444, + .fmt_bitmask = BIT(24), + }, + { + .dts_name = "y_u_v8", + .id = XILINX_FRMBUF_FMT_Y_U_V8, + .bpw = 32, + .ppw = 4, + .num_planes = 3, + .v4l2_fmt = V4L2_PIX_FMT_YUV444P, + .drm_fmt = DRM_FORMAT_YUV444, + .fmt_bitmask = BIT(24), + }, + { + .dts_name = "y_u_v10", + .id = XILINX_FRMBUF_FMT_Y_U_V10, + .bpw = 32, + .ppw = 3, + .num_planes = 3, + .v4l2_fmt = V4L2_PIX_FMT_X403, + .drm_fmt = DRM_FORMAT_X403, + .fmt_bitmask = BIT(25), + }, +}; + +/** + * struct xilinx_frmbuf_feature - dt or IP property structure + * @direction: dma transfer mode and direction + * @flags: Bitmask of properties enabled in IP or dt + */ +struct xilinx_frmbuf_feature { + enum dma_transfer_direction direction; + u32 flags; +}; + +/** + * struct xilinx_frmbuf_device - dma device structure + * @regs: I/O mapped base address + * @dev: Device Structure + * @common: DMA device structure + * @chan: Driver specific dma channel + * @rst_gpio: GPIO reset + * @enabled_vid_fmts: Bitmask of video formats enabled in hardware + * @drm_memory_fmts: Array of supported DRM fourcc codes + * @drm_fmt_cnt: Count of supported DRM fourcc codes + * @v4l2_memory_fmts: Array of supported V4L2 fourcc codes + * @v4l2_fmt_cnt: Count of supported V4L2 fourcc codes + * @cfg: Pointer to Framebuffer Feature config struct + * @max_width: Maximum pixel width supported in IP. + * @max_height: Maximum number of lines supported in IP. + * @ppc: Pixels per clock supported in IP. + * @ap_clk: Video core clock + */ +struct xilinx_frmbuf_device { + void __iomem *regs; + struct device *dev; + struct dma_device common; + struct xilinx_frmbuf_chan chan; + struct gpio_desc *rst_gpio; + u32 enabled_vid_fmts; + u32 drm_memory_fmts[ARRAY_SIZE(xilinx_frmbuf_formats)]; + u32 drm_fmt_cnt; + u32 v4l2_memory_fmts[ARRAY_SIZE(xilinx_frmbuf_formats)]; + u32 v4l2_fmt_cnt; + const struct xilinx_frmbuf_feature *cfg; + u32 max_width; + u32 max_height; + u32 ppc; + struct clk *ap_clk; +}; + +static const struct xilinx_frmbuf_feature xlnx_fbwr_cfg_v20 = { + .direction = DMA_DEV_TO_MEM, +}; + +static const struct xilinx_frmbuf_feature xlnx_fbwr_cfg_v21 = { + .direction = DMA_DEV_TO_MEM, + .flags = XILINX_PPC_PROP | XILINX_FLUSH_PROP + | XILINX_FID_PROP | XILINX_CLK_PROP, +}; + +static const struct xilinx_frmbuf_feature xlnx_fbwr_cfg_v22 = { + .direction = DMA_DEV_TO_MEM, + .flags = XILINX_PPC_PROP | XILINX_FLUSH_PROP + | XILINX_FID_PROP | XILINX_CLK_PROP + | XILINX_THREE_PLANES_PROP, +}; + +static const struct xilinx_frmbuf_feature xlnx_fbrd_cfg_v20 = { + .direction = DMA_MEM_TO_DEV, +}; + +static const struct xilinx_frmbuf_feature xlnx_fbrd_cfg_v21 = { + .direction = DMA_MEM_TO_DEV, + .flags = XILINX_PPC_PROP | XILINX_FLUSH_PROP + | XILINX_FID_PROP | XILINX_CLK_PROP, +}; + +static const struct xilinx_frmbuf_feature xlnx_fbrd_cfg_v22 = { + .direction = DMA_MEM_TO_DEV, + .flags = XILINX_PPC_PROP | XILINX_FLUSH_PROP + | XILINX_FID_PROP | XILINX_CLK_PROP + | XILINX_THREE_PLANES_PROP + | XILINX_FID_ERR_DETECT_PROP, +}; + +static const struct of_device_id xilinx_frmbuf_of_ids[] = { + { .compatible = "xlnx,axi-frmbuf-wr-v2", + .data = (void *)&xlnx_fbwr_cfg_v20}, + { .compatible = "xlnx,axi-frmbuf-wr-v2.1", + .data = (void *)&xlnx_fbwr_cfg_v21}, + { .compatible = "xlnx,axi-frmbuf-wr-v2.2", + .data = (void *)&xlnx_fbwr_cfg_v22}, + { .compatible = "xlnx,axi-frmbuf-rd-v2", + .data = (void *)&xlnx_fbrd_cfg_v20}, + { .compatible = "xlnx,axi-frmbuf-rd-v2.1", + .data = (void *)&xlnx_fbrd_cfg_v21}, + { .compatible = "xlnx,axi-frmbuf-rd-v2.2", + .data = (void *)&xlnx_fbrd_cfg_v22}, + {/* end of list */} +}; + +/******************************PROTOTYPES*************************************/ +#define to_xilinx_chan(chan) \ + container_of(chan, struct xilinx_frmbuf_chan, common) +#define to_dma_tx_descriptor(tx) \ + container_of(tx, struct xilinx_frmbuf_tx_descriptor, async_tx) + +static inline u32 frmbuf_read(struct xilinx_frmbuf_chan *chan, u32 reg) +{ + return ioread32(chan->xdev->regs + reg); +} + +static inline void frmbuf_write(struct xilinx_frmbuf_chan *chan, u32 reg, + u32 value) +{ + iowrite32(value, chan->xdev->regs + reg); +} + +static inline void frmbuf_writeq(struct xilinx_frmbuf_chan *chan, u32 reg, + u64 value) +{ + iowrite32(lower_32_bits(value), chan->xdev->regs + reg); + iowrite32(upper_32_bits(value), chan->xdev->regs + reg + 4); +} + +static void writeq_addr(struct xilinx_frmbuf_chan *chan, u32 reg, + dma_addr_t addr) +{ + frmbuf_writeq(chan, reg, (u64)addr); +} + +static void write_addr(struct xilinx_frmbuf_chan *chan, u32 reg, + dma_addr_t addr) +{ + frmbuf_write(chan, reg, addr); +} + +static inline void frmbuf_clr(struct xilinx_frmbuf_chan *chan, u32 reg, + u32 clr) +{ + frmbuf_write(chan, reg, frmbuf_read(chan, reg) & ~clr); +} + +static inline void frmbuf_set(struct xilinx_frmbuf_chan *chan, u32 reg, + u32 set) +{ + frmbuf_write(chan, reg, frmbuf_read(chan, reg) | set); +} + +static void frmbuf_init_format_array(struct xilinx_frmbuf_device *xdev) +{ + u32 i, cnt; + + for (i = 0; i < ARRAY_SIZE(xilinx_frmbuf_formats); i++) { + if (!(xdev->enabled_vid_fmts & + xilinx_frmbuf_formats[i].fmt_bitmask)) + continue; + + if (xilinx_frmbuf_formats[i].drm_fmt) { + cnt = xdev->drm_fmt_cnt++; + xdev->drm_memory_fmts[cnt] = + xilinx_frmbuf_formats[i].drm_fmt; + } + + if (xilinx_frmbuf_formats[i].v4l2_fmt) { + cnt = xdev->v4l2_fmt_cnt++; + xdev->v4l2_memory_fmts[cnt] = + xilinx_frmbuf_formats[i].v4l2_fmt; + } + } +} + +static struct xilinx_frmbuf_chan *frmbuf_find_chan(struct dma_chan *chan) +{ + struct xilinx_frmbuf_chan *xil_chan; + bool found_xchan = false; + + mutex_lock(&frmbuf_chan_list_lock); + list_for_each_entry(xil_chan, &frmbuf_chan_list, chan_node) { + if (chan == &xil_chan->common) { + found_xchan = true; + break; + } + } + mutex_unlock(&frmbuf_chan_list_lock); + + if (!found_xchan) { + dev_dbg(chan->device->dev, + "dma chan not a Video Framebuffer channel instance\n"); + return ERR_PTR(-EINVAL); + } + + return xil_chan; +} + +static struct xilinx_frmbuf_device *frmbuf_find_dev(struct dma_chan *chan) +{ + struct xilinx_frmbuf_chan *xchan, *temp; + struct xilinx_frmbuf_device *xdev; + bool is_frmbuf_chan = false; + + list_for_each_entry_safe(xchan, temp, &frmbuf_chan_list, chan_node) { + if (chan == &xchan->common) + is_frmbuf_chan = true; + } + + if (!is_frmbuf_chan) + return ERR_PTR(-ENODEV); + + xchan = to_xilinx_chan(chan); + xdev = container_of(xchan, struct xilinx_frmbuf_device, chan); + + return xdev; +} + +static int frmbuf_verify_format(struct dma_chan *chan, u32 fourcc, u32 type) +{ + struct xilinx_frmbuf_chan *xil_chan = to_xilinx_chan(chan); + u32 i, sz = ARRAY_SIZE(xilinx_frmbuf_formats); + + for (i = 0; i < sz; i++) { + if ((type == XDMA_DRM && + fourcc != xilinx_frmbuf_formats[i].drm_fmt) || + (type == XDMA_V4L2 && + fourcc != xilinx_frmbuf_formats[i].v4l2_fmt)) + continue; + + if (!(xilinx_frmbuf_formats[i].fmt_bitmask & + xil_chan->xdev->enabled_vid_fmts)) + return -EINVAL; + + /* + * The Alpha color formats are supported in Framebuffer Read + * IP only as corresponding DRM formats. + */ + if (type == XDMA_DRM && + (xilinx_frmbuf_formats[i].drm_fmt == DRM_FORMAT_ABGR8888 || + xilinx_frmbuf_formats[i].drm_fmt == DRM_FORMAT_ARGB8888 || + xilinx_frmbuf_formats[i].drm_fmt == DRM_FORMAT_AVUY) && + xil_chan->direction != DMA_MEM_TO_DEV) + return -EINVAL; + + xil_chan->vid_fmt = &xilinx_frmbuf_formats[i]; + return 0; + } + return -EINVAL; +} + +static void xilinx_xdma_set_config(struct dma_chan *chan, u32 fourcc, u32 type) +{ + struct xilinx_frmbuf_chan *xil_chan; + struct xilinx_frmbuf_device *xdev; + const struct xilinx_frmbuf_format_desc *old_vid_fmt; + int ret; + + xil_chan = frmbuf_find_chan(chan); + if (IS_ERR(xil_chan)) + return; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return; + + /* Save old video format */ + old_vid_fmt = xil_chan->vid_fmt; + + ret = frmbuf_verify_format(chan, fourcc, type); + if (ret == -EINVAL) { + dev_err(chan->device->dev, + "Framebuffer not configured for fourcc 0x%x\n", + fourcc); + return; + } + + if ((!(xdev->cfg->flags & XILINX_THREE_PLANES_PROP)) && + (xil_chan->vid_fmt->id == XILINX_FRMBUF_FMT_Y_U_V8 || + xil_chan->vid_fmt->id == XILINX_FRMBUF_FMT_Y_U_V10)) { + dev_err(chan->device->dev, "doesn't support %s format\n", + xil_chan->vid_fmt->dts_name); + /* Restore to old video format */ + xil_chan->vid_fmt = old_vid_fmt; + return; + } +} + +void xilinx_xdma_set_mode(struct dma_chan *chan, enum operation_mode + mode) +{ + struct xilinx_frmbuf_chan *xil_chan; + + xil_chan = frmbuf_find_chan(chan); + if (IS_ERR(xil_chan)) + return; + + xil_chan->mode = mode; + + return; + +} EXPORT_SYMBOL_GPL(xilinx_xdma_set_mode); + +void xilinx_xdma_drm_config(struct dma_chan *chan, u32 drm_fourcc) +{ + xilinx_xdma_set_config(chan, drm_fourcc, XDMA_DRM); + +} EXPORT_SYMBOL_GPL(xilinx_xdma_drm_config); + +void xilinx_xdma_v4l2_config(struct dma_chan *chan, u32 v4l2_fourcc) +{ + xilinx_xdma_set_config(chan, v4l2_fourcc, XDMA_V4L2); + +} EXPORT_SYMBOL_GPL(xilinx_xdma_v4l2_config); + +int xilinx_xdma_get_drm_vid_fmts(struct dma_chan *chan, u32 *fmt_cnt, + u32 **fmts) +{ + struct xilinx_frmbuf_device *xdev; + + xdev = frmbuf_find_dev(chan); + + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + *fmt_cnt = xdev->drm_fmt_cnt; + *fmts = xdev->drm_memory_fmts; + + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_drm_vid_fmts); + +int xilinx_xdma_get_v4l2_vid_fmts(struct dma_chan *chan, u32 *fmt_cnt, + u32 **fmts) +{ + struct xilinx_frmbuf_device *xdev; + + xdev = frmbuf_find_dev(chan); + + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + *fmt_cnt = xdev->v4l2_fmt_cnt; + *fmts = xdev->v4l2_memory_fmts; + + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_v4l2_vid_fmts); + +int xilinx_xdma_get_fid(struct dma_chan *chan, + struct dma_async_tx_descriptor *async_tx, u32 *fid) +{ + struct xilinx_frmbuf_device *xdev; + struct xilinx_frmbuf_tx_descriptor *desc; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + if (!async_tx || !fid) + return -EINVAL; + + if (xdev->chan.direction != DMA_DEV_TO_MEM) + return -EINVAL; + + desc = to_dma_tx_descriptor(async_tx); + if (!desc) + return -EINVAL; + + *fid = desc->fid; + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_fid); + +int xilinx_xdma_set_fid(struct dma_chan *chan, + struct dma_async_tx_descriptor *async_tx, u32 fid) +{ + struct xilinx_frmbuf_device *xdev; + struct xilinx_frmbuf_tx_descriptor *desc; + + if (fid > 1 || !async_tx) + return -EINVAL; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + if (xdev->chan.direction != DMA_MEM_TO_DEV) + return -EINVAL; + + desc = to_dma_tx_descriptor(async_tx); + if (!desc) + return -EINVAL; + + desc->fid = fid; + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_set_fid); + +int xilinx_xdma_get_fid_err_flag(struct dma_chan *chan, + u32 *fid_err_flag) +{ + struct xilinx_frmbuf_device *xdev; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + if (xdev->chan.direction != DMA_MEM_TO_DEV || xdev->chan.idle) + return -EINVAL; + + *fid_err_flag = xdev->chan.fid_err_flag; + + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_fid_err_flag); + +int xilinx_xdma_get_fid_out(struct dma_chan *chan, + u32 *fid_out_val) +{ + struct xilinx_frmbuf_device *xdev; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + if (xdev->chan.direction != DMA_MEM_TO_DEV || xdev->chan.idle) + return -EINVAL; + + *fid_out_val = xdev->chan.fid_out_val; + + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_fid_out); + +int xilinx_xdma_get_width_align(struct dma_chan *chan, u32 *width_align) +{ + struct xilinx_frmbuf_device *xdev; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + *width_align = xdev->ppc; + + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_width_align); + +int xilinx_xdma_get_earlycb(struct dma_chan *chan, + struct dma_async_tx_descriptor *async_tx, + u32 *earlycb) +{ + struct xilinx_frmbuf_device *xdev; + struct xilinx_frmbuf_tx_descriptor *desc; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + if (!async_tx || !earlycb) + return -EINVAL; + + desc = to_dma_tx_descriptor(async_tx); + if (!desc) + return -EINVAL; + + *earlycb = desc->earlycb; + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_get_earlycb); + +int xilinx_xdma_set_earlycb(struct dma_chan *chan, + struct dma_async_tx_descriptor *async_tx, + u32 earlycb) +{ + struct xilinx_frmbuf_device *xdev; + struct xilinx_frmbuf_tx_descriptor *desc; + + if (!async_tx) + return -EINVAL; + + xdev = frmbuf_find_dev(chan); + if (IS_ERR(xdev)) + return PTR_ERR(xdev); + + desc = to_dma_tx_descriptor(async_tx); + if (!desc) + return -EINVAL; + + desc->earlycb = earlycb; + return 0; +} +EXPORT_SYMBOL(xilinx_xdma_set_earlycb); + +/** + * of_dma_xilinx_xlate - Translation function + * @dma_spec: Pointer to DMA specifier as found in the device tree + * @ofdma: Pointer to DMA controller data + * + * Return: DMA channel pointer on success or error code on error + */ +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct xilinx_frmbuf_device *xdev = ofdma->of_dma_data; + + return dma_get_slave_channel(&xdev->chan.common); +} + +/* ----------------------------------------------------------------------------- + * Descriptors alloc and free + */ + +/** + * xilinx_frmbuf_alloc_tx_descriptor - Allocate transaction descriptor + * @chan: Driver specific dma channel + * + * Return: The allocated descriptor on success and NULL on failure. + */ +static struct xilinx_frmbuf_tx_descriptor * +xilinx_frmbuf_alloc_tx_descriptor(struct xilinx_frmbuf_chan *chan) +{ + struct xilinx_frmbuf_tx_descriptor *desc; + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return NULL; + + return desc; +} + +/** + * xilinx_frmbuf_free_desc_list - Free descriptors list + * @chan: Driver specific dma channel + * @list: List to parse and delete the descriptor + */ +static void xilinx_frmbuf_free_desc_list(struct xilinx_frmbuf_chan *chan, + struct list_head *list) +{ + struct xilinx_frmbuf_tx_descriptor *desc, *next; + + list_for_each_entry_safe(desc, next, list, node) { + list_del(&desc->node); + kfree(desc); + } +} + +/** + * xilinx_frmbuf_free_descriptors - Free channel descriptors + * @chan: Driver specific dma channel + */ +static void xilinx_frmbuf_free_descriptors(struct xilinx_frmbuf_chan *chan) +{ + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + + xilinx_frmbuf_free_desc_list(chan, &chan->pending_list); + xilinx_frmbuf_free_desc_list(chan, &chan->done_list); + kfree(chan->active_desc); + kfree(chan->staged_desc); + + chan->staged_desc = NULL; + chan->active_desc = NULL; + INIT_LIST_HEAD(&chan->pending_list); + INIT_LIST_HEAD(&chan->done_list); + + spin_unlock_irqrestore(&chan->lock, flags); +} + +/** + * xilinx_frmbuf_free_chan_resources - Free channel resources + * @dchan: DMA channel + */ +static void xilinx_frmbuf_free_chan_resources(struct dma_chan *dchan) +{ + struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan); + + xilinx_frmbuf_free_descriptors(chan); +} + +/** + * xilinx_frmbuf_chan_desc_cleanup - Clean channel descriptors + * @chan: Driver specific dma channel + */ +static void xilinx_frmbuf_chan_desc_cleanup(struct xilinx_frmbuf_chan *chan) +{ + struct xilinx_frmbuf_tx_descriptor *desc, *next; + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + + list_for_each_entry_safe(desc, next, &chan->done_list, node) { + dma_async_tx_callback callback; + void *callback_param; + + list_del(&desc->node); + + /* Run the link descriptor callback function */ + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + if (callback) { + spin_unlock_irqrestore(&chan->lock, flags); + callback(callback_param); + spin_lock_irqsave(&chan->lock, flags); + } + + /* Run any dependencies, then free the descriptor */ + dma_run_dependencies(&desc->async_tx); + kfree(desc); + } + + spin_unlock_irqrestore(&chan->lock, flags); +} + +/** + * xilinx_frmbuf_do_tasklet - Schedule completion tasklet + * @data: Pointer to the Xilinx frmbuf channel structure + */ +static void xilinx_frmbuf_do_tasklet(unsigned long data) +{ + struct xilinx_frmbuf_chan *chan = (struct xilinx_frmbuf_chan *)data; + + xilinx_frmbuf_chan_desc_cleanup(chan); +} + +/** + * xilinx_frmbuf_alloc_chan_resources - Allocate channel resources + * @dchan: DMA channel + * + * Return: '0' on success and failure value on error + */ +static int xilinx_frmbuf_alloc_chan_resources(struct dma_chan *dchan) +{ + dma_cookie_init(dchan); + + return 0; +} + +/** + * xilinx_frmbuf_tx_status - Get frmbuf transaction status + * @dchan: DMA channel + * @cookie: Transaction identifier + * @txstate: Transaction state + * + * Return: fmrbuf transaction status + */ +static enum dma_status xilinx_frmbuf_tx_status(struct dma_chan *dchan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + return dma_cookie_status(dchan, cookie, txstate); +} + +/** + * xilinx_frmbuf_halt - Halt frmbuf channel + * @chan: Driver specific dma channel + */ +static void xilinx_frmbuf_halt(struct xilinx_frmbuf_chan *chan) +{ + frmbuf_clr(chan, XILINX_FRMBUF_CTRL_OFFSET, + XILINX_FRMBUF_CTRL_AP_START | chan->mode); + chan->idle = true; +} + +/** + * xilinx_frmbuf_start - Start dma channel + * @chan: Driver specific dma channel + */ +static void xilinx_frmbuf_start(struct xilinx_frmbuf_chan *chan) +{ + frmbuf_set(chan, XILINX_FRMBUF_CTRL_OFFSET, + XILINX_FRMBUF_CTRL_AP_START | chan->mode); + chan->idle = false; +} + +/** + * xilinx_frmbuf_complete_descriptor - Mark the active descriptor as complete + * This function is invoked with spinlock held + * @chan : xilinx frmbuf channel + * + * CONTEXT: hardirq + */ +static void xilinx_frmbuf_complete_descriptor(struct xilinx_frmbuf_chan *chan) +{ + struct xilinx_frmbuf_tx_descriptor *desc = chan->active_desc; + + /* + * In case of frame buffer write, read the fid register + * and associate it with descriptor + */ + if (chan->direction == DMA_DEV_TO_MEM && chan->hw_fid) + desc->fid = frmbuf_read(chan, XILINX_FRMBUF_FID_OFFSET) & + XILINX_FRMBUF_FID_MASK; + + dma_cookie_complete(&desc->async_tx); + list_add_tail(&desc->node, &chan->done_list); +} + +/** + * xilinx_frmbuf_start_transfer - Starts frmbuf transfer + * @chan: Driver specific channel struct pointer + */ +static void xilinx_frmbuf_start_transfer(struct xilinx_frmbuf_chan *chan) +{ + struct xilinx_frmbuf_tx_descriptor *desc; + struct xilinx_frmbuf_device *xdev; + + xdev = container_of(chan, struct xilinx_frmbuf_device, chan); + + if (!chan->idle) + return; + + if (chan->staged_desc) { + chan->active_desc = chan->staged_desc; + chan->staged_desc = NULL; + } + + if (list_empty(&chan->pending_list)) + return; + + desc = list_first_entry(&chan->pending_list, + struct xilinx_frmbuf_tx_descriptor, + node); + + if (desc->earlycb == EARLY_CALLBACK_START_DESC) { + dma_async_tx_callback callback; + void *callback_param; + + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + if (callback) { + callback(callback_param); + desc->async_tx.callback = NULL; + chan->active_desc = desc; + } + } + + /* Start the transfer */ + chan->write_addr(chan, XILINX_FRMBUF_ADDR_OFFSET, + desc->hw.luma_plane_addr); + chan->write_addr(chan, XILINX_FRMBUF_ADDR2_OFFSET, + desc->hw.chroma_plane_addr[0]); + if (xdev->cfg->flags & XILINX_THREE_PLANES_PROP) { + if (chan->direction == DMA_MEM_TO_DEV) + chan->write_addr(chan, XILINX_FRMBUF_RD_ADDR3_OFFSET, + desc->hw.chroma_plane_addr[1]); + else + chan->write_addr(chan, XILINX_FRMBUF_ADDR3_OFFSET, + desc->hw.chroma_plane_addr[1]); + } + + /* HW expects these parameters to be same for one transaction */ + frmbuf_write(chan, XILINX_FRMBUF_WIDTH_OFFSET, desc->hw.hsize); + frmbuf_write(chan, XILINX_FRMBUF_STRIDE_OFFSET, desc->hw.stride); + frmbuf_write(chan, XILINX_FRMBUF_HEIGHT_OFFSET, desc->hw.vsize); + frmbuf_write(chan, XILINX_FRMBUF_FMT_OFFSET, chan->vid_fmt->id); + + /* If it is framebuffer read IP set the FID */ + if (chan->direction == DMA_MEM_TO_DEV && chan->hw_fid) + frmbuf_write(chan, XILINX_FRMBUF_FID_OFFSET, desc->fid); + + /* Start the hardware */ + xilinx_frmbuf_start(chan); + list_del(&desc->node); + + /* No staging descriptor required when auto restart is disabled */ + if (chan->mode == AUTO_RESTART) + chan->staged_desc = desc; + else + chan->active_desc = desc; +} + +/** + * xilinx_frmbuf_issue_pending - Issue pending transactions + * @dchan: DMA channel + */ +static void xilinx_frmbuf_issue_pending(struct dma_chan *dchan) +{ + struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan); + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + xilinx_frmbuf_start_transfer(chan); + spin_unlock_irqrestore(&chan->lock, flags); +} + +/** + * xilinx_frmbuf_reset - Reset frmbuf channel + * @chan: Driver specific dma channel + */ +static void xilinx_frmbuf_reset(struct xilinx_frmbuf_chan *chan) +{ + /* reset ip */ + gpiod_set_value(chan->xdev->rst_gpio, 1); + udelay(1); + gpiod_set_value(chan->xdev->rst_gpio, 0); +} + +/** + * xilinx_frmbuf_chan_reset - Reset frmbuf channel and enable interrupts + * @chan: Driver specific frmbuf channel + */ +static void xilinx_frmbuf_chan_reset(struct xilinx_frmbuf_chan *chan) +{ + xilinx_frmbuf_reset(chan); + frmbuf_write(chan, XILINX_FRMBUF_IE_OFFSET, XILINX_FRMBUF_IE_AP_DONE); + frmbuf_write(chan, XILINX_FRMBUF_GIE_OFFSET, XILINX_FRMBUF_GIE_EN); + chan->fid_err_flag = 0; + chan->fid_out_val = 0; +} + +/** + * xilinx_frmbuf_irq_handler - frmbuf Interrupt handler + * @irq: IRQ number + * @data: Pointer to the Xilinx frmbuf channel structure + * + * Return: IRQ_HANDLED/IRQ_NONE + */ +static irqreturn_t xilinx_frmbuf_irq_handler(int irq, void *data) +{ + struct xilinx_frmbuf_chan *chan = data; + u32 status; + dma_async_tx_callback callback = NULL; + void *callback_param; + struct xilinx_frmbuf_tx_descriptor *desc; + + status = frmbuf_read(chan, XILINX_FRMBUF_ISR_OFFSET); + if (!(status & XILINX_FRMBUF_ISR_ALL_IRQ_MASK)) + return IRQ_NONE; + + frmbuf_write(chan, XILINX_FRMBUF_ISR_OFFSET, + status & XILINX_FRMBUF_ISR_ALL_IRQ_MASK); + + /* Check if callback function needs to be called early */ + desc = chan->staged_desc; + if (desc && desc->earlycb == EARLY_CALLBACK) { + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + if (callback) { + callback(callback_param); + desc->async_tx.callback = NULL; + } + } + + if (status & XILINX_FRMBUF_ISR_AP_DONE_IRQ) { + spin_lock(&chan->lock); + chan->idle = true; + if (chan->active_desc) { + xilinx_frmbuf_complete_descriptor(chan); + chan->active_desc = NULL; + } + + /* Update fid err detect flag and out value */ + if (chan->direction == DMA_MEM_TO_DEV && + chan->hw_fid && chan->idle && + chan->xdev->cfg->flags & XILINX_FID_ERR_DETECT_PROP) { + if (chan->mode == AUTO_RESTART) + chan->fid_mode = FID_MODE_2; + else + chan->fid_mode = FID_MODE_1; + + frmbuf_write(chan, XILINX_FRMBUF_FID_MODE_OFFSET, + chan->fid_mode); + dev_dbg(chan->xdev->dev, "fid mode = %d\n", + frmbuf_read(chan, XILINX_FRMBUF_FID_MODE_OFFSET)); + + chan->fid_err_flag = frmbuf_read(chan, + XILINX_FRMBUF_FID_ERR_OFFSET) & + XILINX_FRMBUF_FID_ERR_MASK; + chan->fid_out_val = frmbuf_read(chan, + XILINX_FRMBUF_FID_OUT_OFFSET) & + XILINX_FRMBUF_FID_OUT_MASK; + dev_dbg(chan->xdev->dev, "fid err cnt = 0x%x\n", + frmbuf_read(chan, XILINX_FRMBUF_FID_ERR_OFFSET)); + } + + xilinx_frmbuf_start_transfer(chan); + spin_unlock(&chan->lock); + } + + tasklet_schedule(&chan->tasklet); + return IRQ_HANDLED; +} + +/** + * xilinx_frmbuf_tx_submit - Submit DMA transaction + * @tx: Async transaction descriptor + * + * Return: cookie value on success and failure value on error + */ +static dma_cookie_t xilinx_frmbuf_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct xilinx_frmbuf_tx_descriptor *desc = to_dma_tx_descriptor(tx); + struct xilinx_frmbuf_chan *chan = to_xilinx_chan(tx->chan); + dma_cookie_t cookie; + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + cookie = dma_cookie_assign(tx); + list_add_tail(&desc->node, &chan->pending_list); + spin_unlock_irqrestore(&chan->lock, flags); + + return cookie; +} + +/** + * xilinx_frmbuf_dma_prep_interleaved - prepare a descriptor for a + * DMA_SLAVE transaction + * @dchan: DMA channel + * @xt: Interleaved template pointer + * @flags: transfer ack flags + * + * Return: Async transaction descriptor on success and NULL on failure + */ +static struct dma_async_tx_descriptor * +xilinx_frmbuf_dma_prep_interleaved(struct dma_chan *dchan, + struct dma_interleaved_template *xt, + unsigned long flags) +{ + struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan); + struct xilinx_frmbuf_tx_descriptor *desc; + struct xilinx_frmbuf_desc_hw *hw; + u32 vsize, hsize; + + if (chan->direction != xt->dir || !chan->vid_fmt) + goto error; + + if (!xt->numf || !xt->sgl[0].size) + goto error; + + if (xt->frame_size != chan->vid_fmt->num_planes) + goto error; + + vsize = xt->numf; + hsize = (xt->sgl[0].size * chan->vid_fmt->ppw * 8) / + chan->vid_fmt->bpw; + /* hsize calc should not have resulted in an odd number */ + if (hsize & 1) + hsize++; + + if (vsize > chan->xdev->max_height || hsize > chan->xdev->max_width) { + dev_dbg(chan->xdev->dev, + "vsize %d max vsize %d hsize %d max hsize %d\n", + vsize, chan->xdev->max_height, hsize, + chan->xdev->max_width); + dev_err(chan->xdev->dev, "Requested size not supported!\n"); + goto error; + } + + desc = xilinx_frmbuf_alloc_tx_descriptor(chan); + if (!desc) + return NULL; + + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); + desc->async_tx.tx_submit = xilinx_frmbuf_tx_submit; + async_tx_ack(&desc->async_tx); + + hw = &desc->hw; + hw->vsize = xt->numf; + hw->stride = xt->sgl[0].icg + xt->sgl[0].size; + hw->hsize = (xt->sgl[0].size * chan->vid_fmt->ppw * 8) / + chan->vid_fmt->bpw; + + /* hsize calc should not have resulted in an odd number */ + if (hw->hsize & 1) + hw->hsize++; + + if (chan->direction == DMA_MEM_TO_DEV) { + hw->luma_plane_addr = xt->src_start; + if (xt->frame_size == 2 || xt->frame_size == 3) + hw->chroma_plane_addr[0] = + xt->src_start + + xt->numf * hw->stride + + xt->sgl[0].src_icg; + if (xt->frame_size == 3) + hw->chroma_plane_addr[1] = + hw->chroma_plane_addr[0] + + xt->numf * hw->stride + + xt->sgl[0].src_icg; + } else { + hw->luma_plane_addr = xt->dst_start; + if (xt->frame_size == 2 || xt->frame_size == 3) + hw->chroma_plane_addr[0] = + xt->dst_start + + xt->numf * hw->stride + + xt->sgl[0].dst_icg; + if (xt->frame_size == 3) + hw->chroma_plane_addr[1] = + hw->chroma_plane_addr[0] + + xt->numf * hw->stride + + xt->sgl[0].dst_icg; + } + + return &desc->async_tx; + +error: + dev_err(chan->xdev->dev, + "Invalid dma template or missing dma video fmt config\n"); + return NULL; +} + +/** + * xilinx_frmbuf_terminate_all - Halt the channel and free descriptors + * @dchan: Driver specific dma channel pointer + * + * Return: 0 + */ +static int xilinx_frmbuf_terminate_all(struct dma_chan *dchan) +{ + struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan); + + xilinx_frmbuf_halt(chan); + xilinx_frmbuf_free_descriptors(chan); + /* worst case frame-to-frame boundary; ensure frame output complete */ + msleep(50); + + if (chan->xdev->cfg->flags & XILINX_FLUSH_PROP) { + u8 count; + + /* + * Flush the framebuffer FIFO and + * wait for max 50ms for flush done + */ + frmbuf_set(chan, XILINX_FRMBUF_CTRL_OFFSET, + XILINX_FRMBUF_CTRL_FLUSH); + for (count = WAIT_FOR_FLUSH_DONE; count > 0; count--) { + if (frmbuf_read(chan, XILINX_FRMBUF_CTRL_OFFSET) & + XILINX_FRMBUF_CTRL_FLUSH_DONE) + break; + usleep_range(2000, 2100); + } + + if (!count) + dev_err(chan->xdev->dev, "Framebuffer Flush not done!\n"); + } + + xilinx_frmbuf_chan_reset(chan); + + return 0; +} + +/** + * xilinx_frmbuf_synchronize - kill tasklet to stop further descr processing + * @dchan: Driver specific dma channel pointer + */ +static void xilinx_frmbuf_synchronize(struct dma_chan *dchan) +{ + struct xilinx_frmbuf_chan *chan = to_xilinx_chan(dchan); + + tasklet_kill(&chan->tasklet); +} + +/* ----------------------------------------------------------------------------- + * Probe and remove + */ + +/** + * xilinx_frmbuf_chan_remove - Per Channel remove function + * @chan: Driver specific dma channel + */ +static void xilinx_frmbuf_chan_remove(struct xilinx_frmbuf_chan *chan) +{ + /* Disable all interrupts */ + frmbuf_clr(chan, XILINX_FRMBUF_IE_OFFSET, + XILINX_FRMBUF_ISR_ALL_IRQ_MASK); + + tasklet_kill(&chan->tasklet); + list_del(&chan->common.device_node); + + mutex_lock(&frmbuf_chan_list_lock); + list_del(&chan->chan_node); + mutex_unlock(&frmbuf_chan_list_lock); +} + +/** + * xilinx_frmbuf_chan_probe - Per Channel Probing + * It get channel features from the device tree entry and + * initialize special channel handling routines + * + * @xdev: Driver specific device structure + * @node: Device node + * + * Return: '0' on success and failure value on error + */ +static int xilinx_frmbuf_chan_probe(struct xilinx_frmbuf_device *xdev, + struct device_node *node) +{ + struct xilinx_frmbuf_chan *chan; + int err; + u32 dma_addr_size = 0; + + chan = &xdev->chan; + + chan->dev = xdev->dev; + chan->xdev = xdev; + chan->idle = true; + chan->fid_err_flag = 0; + chan->fid_out_val = 0; + chan->mode = AUTO_RESTART; + + err = of_property_read_u32(node, "xlnx,dma-addr-width", + &dma_addr_size); + if (err || (dma_addr_size != 32 && dma_addr_size != 64)) { + dev_err(xdev->dev, "missing or invalid addr width dts prop\n"); + return err; + } + + if (dma_addr_size == 64 && sizeof(dma_addr_t) == sizeof(u64)) + chan->write_addr = writeq_addr; + else + chan->write_addr = write_addr; + + if (xdev->cfg->flags & XILINX_FID_PROP) + chan->hw_fid = of_property_read_bool(node, "xlnx,fid"); + + spin_lock_init(&chan->lock); + INIT_LIST_HEAD(&chan->pending_list); + INIT_LIST_HEAD(&chan->done_list); + + chan->irq = irq_of_parse_and_map(node, 0); + err = devm_request_irq(xdev->dev, chan->irq, xilinx_frmbuf_irq_handler, + IRQF_SHARED, "xilinx_framebuffer", chan); + + if (err) { + dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq); + return err; + } + + tasklet_init(&chan->tasklet, xilinx_frmbuf_do_tasklet, + (unsigned long)chan); + + /* + * Initialize the DMA channel and add it to the DMA engine channels + * list. + */ + chan->common.device = &xdev->common; + + list_add_tail(&chan->common.device_node, &xdev->common.channels); + + mutex_lock(&frmbuf_chan_list_lock); + list_add_tail(&chan->chan_node, &frmbuf_chan_list); + mutex_unlock(&frmbuf_chan_list_lock); + + xilinx_frmbuf_chan_reset(chan); + + return 0; +} + +/** + * xilinx_frmbuf_probe - Driver probe function + * @pdev: Pointer to the platform_device structure + * + * Return: '0' on success and failure value on error + */ +static int xilinx_frmbuf_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct xilinx_frmbuf_device *xdev; + struct resource *io; + enum dma_transfer_direction dma_dir; + const struct of_device_id *match; + int err; + u32 i, j, align, max_width, max_height; + int hw_vid_fmt_cnt; + const char *vid_fmts[ARRAY_SIZE(xilinx_frmbuf_formats)]; + + xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); + if (!xdev) + return -ENOMEM; + + xdev->dev = &pdev->dev; + + match = of_match_node(xilinx_frmbuf_of_ids, node); + if (!match) + return -ENODEV; + + xdev->cfg = match->data; + + dma_dir = (enum dma_transfer_direction)xdev->cfg->direction; + + if (xdev->cfg->flags & XILINX_CLK_PROP) { + xdev->ap_clk = devm_clk_get(xdev->dev, "ap_clk"); + if (IS_ERR(xdev->ap_clk)) { + err = PTR_ERR(xdev->ap_clk); + dev_err(xdev->dev, "failed to get ap_clk (%d)\n", err); + return err; + } + } else { + dev_info(xdev->dev, "assuming clock is enabled!\n"); + } + + xdev->rst_gpio = devm_gpiod_get(&pdev->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(xdev->rst_gpio)) { + err = PTR_ERR(xdev->rst_gpio); + if (err == -EPROBE_DEFER) + dev_info(&pdev->dev, + "Probe deferred due to GPIO reset defer\n"); + else + dev_err(&pdev->dev, + "Unable to locate reset property in dt\n"); + return err; + } + + gpiod_set_value_cansleep(xdev->rst_gpio, 0x0); + + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + xdev->regs = devm_ioremap_resource(&pdev->dev, io); + if (IS_ERR(xdev->regs)) + return PTR_ERR(xdev->regs); + + if (xdev->cfg->flags & XILINX_THREE_PLANES_PROP) + max_height = 8640; + else + max_height = 4320; + + err = of_property_read_u32(node, "xlnx,max-height", &xdev->max_height); + if (err < 0) { + dev_err(xdev->dev, "xlnx,max-height is missing!"); + return -EINVAL; + } else if (xdev->max_height > max_height || + xdev->max_height < XILINX_FRMBUF_MIN_HEIGHT) { + dev_err(&pdev->dev, "Invalid height in dt"); + return -EINVAL; + } + + if (xdev->cfg->flags & XILINX_THREE_PLANES_PROP) + max_width = 15360; + else + max_width = 8192; + + err = of_property_read_u32(node, "xlnx,max-width", &xdev->max_width); + if (err < 0) { + dev_err(xdev->dev, "xlnx,max-width is missing!"); + return -EINVAL; + } else if (xdev->max_width > max_width || + xdev->max_width < XILINX_FRMBUF_MIN_WIDTH) { + dev_err(&pdev->dev, "Invalid width in dt"); + return -EINVAL; + } + + /* Initialize the DMA engine */ + if (xdev->cfg->flags & XILINX_PPC_PROP) { + err = of_property_read_u32(node, "xlnx,pixels-per-clock", &xdev->ppc); + if (err || (xdev->ppc != 1 && xdev->ppc != 2 && + xdev->ppc != 4 && xdev->ppc != 8)) { + dev_err(&pdev->dev, "missing or invalid pixels per clock dts prop\n"); + return err; + } + err = of_property_read_u32(node, "xlnx,dma-align", &align); + if (err) + align = xdev->ppc * XILINX_FRMBUF_ALIGN_MUL; + + if (align < (xdev->ppc * XILINX_FRMBUF_ALIGN_MUL) || + ffs(align) != fls(align)) { + dev_err(&pdev->dev, "invalid dma align dts prop\n"); + return -EINVAL; + } + } else { + align = 16; + } + + xdev->common.copy_align = (enum dmaengine_alignment)(fls(align) - 1); + xdev->common.dev = &pdev->dev; + + if (xdev->cfg->flags & XILINX_CLK_PROP) { + err = clk_prepare_enable(xdev->ap_clk); + if (err) { + dev_err(&pdev->dev, " failed to enable ap_clk (%d)\n", + err); + return err; + } + } + + INIT_LIST_HEAD(&xdev->common.channels); + dma_cap_set(DMA_SLAVE, xdev->common.cap_mask); + dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask); + + /* Initialize the channels */ + err = xilinx_frmbuf_chan_probe(xdev, node); + if (err < 0) + goto disable_clk; + + xdev->chan.direction = dma_dir; + + if (xdev->chan.direction == DMA_DEV_TO_MEM) { + xdev->common.directions = BIT(DMA_DEV_TO_MEM); + dev_info(&pdev->dev, "Xilinx AXI frmbuf DMA_DEV_TO_MEM\n"); + } else if (xdev->chan.direction == DMA_MEM_TO_DEV) { + xdev->common.directions = BIT(DMA_MEM_TO_DEV); + dev_info(&pdev->dev, "Xilinx AXI frmbuf DMA_MEM_TO_DEV\n"); + } else { + err = -EINVAL; + goto remove_chan; + } + + /* read supported video formats and update internal table */ + hw_vid_fmt_cnt = of_property_count_strings(node, "xlnx,vid-formats"); + + err = of_property_read_string_array(node, "xlnx,vid-formats", + vid_fmts, hw_vid_fmt_cnt); + if (err < 0) { + dev_err(&pdev->dev, + "Missing or invalid xlnx,vid-formats dts prop\n"); + goto remove_chan; + } + + for (i = 0; i < hw_vid_fmt_cnt; i++) { + const char *vid_fmt_name = vid_fmts[i]; + + for (j = 0; j < ARRAY_SIZE(xilinx_frmbuf_formats); j++) { + const char *dts_name = + xilinx_frmbuf_formats[j].dts_name; + + if (strcmp(vid_fmt_name, dts_name)) + continue; + + xdev->enabled_vid_fmts |= + xilinx_frmbuf_formats[j].fmt_bitmask; + } + } + + /* Determine supported vid framework formats */ + frmbuf_init_format_array(xdev); + + xdev->common.device_alloc_chan_resources = + xilinx_frmbuf_alloc_chan_resources; + xdev->common.device_free_chan_resources = + xilinx_frmbuf_free_chan_resources; + xdev->common.device_prep_interleaved_dma = + xilinx_frmbuf_dma_prep_interleaved; + xdev->common.device_terminate_all = xilinx_frmbuf_terminate_all; + xdev->common.device_synchronize = xilinx_frmbuf_synchronize; + xdev->common.device_tx_status = xilinx_frmbuf_tx_status; + xdev->common.device_issue_pending = xilinx_frmbuf_issue_pending; + + platform_set_drvdata(pdev, xdev); + + /* Register the DMA engine with the core */ + dma_async_device_register(&xdev->common); + + err = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev); + if (err < 0) { + dev_err(&pdev->dev, "Unable to register DMA to DT\n"); + goto error; + } + + dev_info(&pdev->dev, "Xilinx AXI FrameBuffer Engine Driver Probed!!\n"); + + return 0; +error: + dma_async_device_unregister(&xdev->common); +remove_chan: + xilinx_frmbuf_chan_remove(&xdev->chan); +disable_clk: + clk_disable_unprepare(xdev->ap_clk); + return err; +} + +/** + * xilinx_frmbuf_remove - Driver remove function + * @pdev: Pointer to the platform_device structure + * + * Return: Always '0' + */ +static int xilinx_frmbuf_remove(struct platform_device *pdev) +{ + struct xilinx_frmbuf_device *xdev = platform_get_drvdata(pdev); + + of_dma_controller_free(pdev->dev.of_node); + + dma_async_device_unregister(&xdev->common); + xilinx_frmbuf_chan_remove(&xdev->chan); + clk_disable_unprepare(xdev->ap_clk); + + return 0; +} + +MODULE_DEVICE_TABLE(of, xilinx_frmbuf_of_ids); + +static struct platform_driver xilinx_frmbuf_driver = { + .driver = { + .name = "xilinx-frmbuf", + .of_match_table = xilinx_frmbuf_of_ids, + }, + .probe = xilinx_frmbuf_probe, + .remove = xilinx_frmbuf_remove, +}; + +module_platform_driver(xilinx_frmbuf_driver); + +MODULE_AUTHOR("Xilinx, Inc."); +MODULE_DESCRIPTION("Xilinx Framebuffer driver"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/dma/xilinx/zynqmp_dma.c +++ linux-xilinx-6.8.0/drivers/dma/xilinx/zynqmp_dma.c @@ -22,10 +22,10 @@ #include "../dmaengine.h" /* Register Offsets */ -#define ZYNQMP_DMA_ISR 0x100 -#define ZYNQMP_DMA_IMR 0x104 -#define ZYNQMP_DMA_IER 0x108 -#define ZYNQMP_DMA_IDS 0x10C +#define ZYNQMP_DMA_ISR (chan->irq_offset + 0x100) +#define ZYNQMP_DMA_IMR (chan->irq_offset + 0x104) +#define ZYNQMP_DMA_IER (chan->irq_offset + 0x108) +#define ZYNQMP_DMA_IDS (chan->irq_offset + 0x10c) #define ZYNQMP_DMA_CTRL0 0x110 #define ZYNQMP_DMA_CTRL1 0x114 #define ZYNQMP_DMA_DATA_ATTR 0x120 @@ -132,6 +132,9 @@ #define ZYNQMP_DMA_IDS_DEFAULT_MASK 0xFFF +/* Reset value for control reg attributes */ +#define ZYNQMP_DMA_RESET_VAL 0x80 + /* Bus width in bits */ #define ZYNQMP_DMA_BUS_WIDTH_64 64 #define ZYNQMP_DMA_BUS_WIDTH_128 128 @@ -145,6 +148,9 @@ #define tx_to_desc(tx) container_of(tx, struct zynqmp_dma_desc_sw, \ async_tx) +/* IRQ Register offset for Versal Gen 2 */ +#define IRQ_REG_OFFSET 0x308 + /** * struct zynqmp_dma_desc_ll - Hw linked list descriptor * @addr: Buffer address @@ -211,6 +217,7 @@ * @bus_width: Bus width * @src_burst_len: Source burst length * @dst_burst_len: Dest burst length + * @irq_offset: Irq register offset */ struct zynqmp_dma_chan { struct zynqmp_dma_device *zdev; @@ -235,6 +242,7 @@ u32 bus_width; u32 src_burst_len; u32 dst_burst_len; + u32 irq_offset; }; /** @@ -253,6 +261,14 @@ struct clk *clk_apb; }; +struct zynqmp_dma_config { + u32 offset; +}; + +static const struct zynqmp_dma_config versal2_dma_config = { + .offset = IRQ_REG_OFFSET, +}; + static inline void zynqmp_dma_writeq(struct zynqmp_dma_chan *chan, u32 reg, u64 value) { @@ -337,6 +353,9 @@ val = readl(chan->regs + ZYNQMP_DMA_ISR); writel(val, chan->regs + ZYNQMP_DMA_ISR); + if (readl(chan->regs + ZYNQMP_DMA_CTRL0) != ZYNQMP_DMA_RESET_VAL) + writel(ZYNQMP_DMA_RESET_VAL, chan->regs + ZYNQMP_DMA_CTRL0); + if (chan->is_dmacoherent) { val = ZYNQMP_DMA_AXCOHRNT; val = (val & ~ZYNQMP_DMA_AXCACHE) | @@ -892,6 +911,7 @@ { struct zynqmp_dma_chan *chan; struct device_node *node = pdev->dev.of_node; + const struct zynqmp_dma_config *match_data; int err; chan = devm_kzalloc(zdev->dev, sizeof(*chan), GFP_KERNEL); @@ -919,6 +939,10 @@ return -EINVAL; } + match_data = of_device_get_match_data(&pdev->dev); + if (match_data) + chan->irq_offset = match_data->offset; + chan->is_dmacoherent = of_property_read_bool(node, "dma-coherent"); zdev->chan = chan; tasklet_setup(&chan->tasklet, zynqmp_dma_do_tasklet); @@ -1161,6 +1185,7 @@ } static const struct of_device_id zynqmp_dma_of_match[] = { + { .compatible = "amd,versal2-dma-1.0", .data = &versal2_dma_config }, { .compatible = "xlnx,zynqmp-dma-1.0", }, {} }; --- linux-xilinx-6.8.0.orig/drivers/dpll/Kconfig +++ linux-xilinx-6.8.0/drivers/dpll/Kconfig @@ -4,4 +4,4 @@ # config DPLL - bool + bool --- linux-xilinx-6.8.0.orig/drivers/dpll/dpll_core.c +++ linux-xilinx-6.8.0/drivers/dpll/dpll_core.c @@ -29,6 +29,8 @@ WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) #define ASSERT_DPLL_NOT_REGISTERED(d) \ WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) +#define ASSERT_DPLL_PIN_REGISTERED(p) \ + WARN_ON_ONCE(!xa_get_mark(&dpll_pin_xa, (p)->id, DPLL_REGISTERED)) struct dpll_device_registration { struct list_head list; @@ -40,6 +42,7 @@ struct list_head list; const struct dpll_pin_ops *ops; void *priv; + void *cookie; }; struct dpll_device *dpll_device_get_by_id(int id) @@ -52,12 +55,14 @@ static struct dpll_pin_registration * dpll_pin_registration_find(struct dpll_pin_ref *ref, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, + void *cookie) { struct dpll_pin_registration *reg; list_for_each_entry(reg, &ref->registration_list, list) { - if (reg->ops == ops && reg->priv == priv) + if (reg->ops == ops && reg->priv == priv && + reg->cookie == cookie) return reg; } return NULL; @@ -65,7 +70,8 @@ static int dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, + void *cookie) { struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; @@ -76,7 +82,7 @@ xa_for_each(xa_pins, i, ref) { if (ref->pin != pin) continue; - reg = dpll_pin_registration_find(ref, ops, priv); + reg = dpll_pin_registration_find(ref, ops, priv, cookie); if (reg) { refcount_inc(&ref->refcount); return 0; @@ -109,6 +115,7 @@ } reg->ops = ops; reg->priv = priv; + reg->cookie = cookie; if (ref_exists) refcount_inc(&ref->refcount); list_add_tail(®->list, &ref->registration_list); @@ -117,7 +124,8 @@ } static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, + void *cookie) { struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; @@ -126,12 +134,12 @@ xa_for_each(xa_pins, i, ref) { if (ref->pin != pin) continue; - reg = dpll_pin_registration_find(ref, ops, priv); + reg = dpll_pin_registration_find(ref, ops, priv, cookie); if (WARN_ON(!reg)) return -EINVAL; + list_del(®->list); + kfree(reg); if (refcount_dec_and_test(&ref->refcount)) { - list_del(®->list); - kfree(reg); xa_erase(xa_pins, i); WARN_ON(!list_empty(&ref->registration_list)); kfree(ref); @@ -144,7 +152,7 @@ static int dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, void *cookie) { struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; @@ -155,7 +163,7 @@ xa_for_each(xa_dplls, i, ref) { if (ref->dpll != dpll) continue; - reg = dpll_pin_registration_find(ref, ops, priv); + reg = dpll_pin_registration_find(ref, ops, priv, cookie); if (reg) { refcount_inc(&ref->refcount); return 0; @@ -188,6 +196,7 @@ } reg->ops = ops; reg->priv = priv; + reg->cookie = cookie; if (ref_exists) refcount_inc(&ref->refcount); list_add_tail(®->list, &ref->registration_list); @@ -197,7 +206,7 @@ static void dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, void *cookie) { struct dpll_pin_registration *reg; struct dpll_pin_ref *ref; @@ -206,12 +215,12 @@ xa_for_each(xa_dplls, i, ref) { if (ref->dpll != dpll) continue; - reg = dpll_pin_registration_find(ref, ops, priv); + reg = dpll_pin_registration_find(ref, ops, priv, cookie); if (WARN_ON(!reg)) return; + list_del(®->list); + kfree(reg); if (refcount_dec_and_test(&ref->refcount)) { - list_del(®->list); - kfree(reg); xa_erase(xa_dplls, i); WARN_ON(!list_empty(&ref->registration_list)); kfree(ref); @@ -440,7 +449,7 @@ sizeof(*src->freq_supported); dst->freq_supported = kmemdup(src->freq_supported, freq_size, GFP_KERNEL); - if (!src->freq_supported) + if (!dst->freq_supported) return -ENOMEM; } if (src->board_label) { @@ -592,14 +601,14 @@ static int __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, void *cookie) { int ret; - ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv); + ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv, cookie); if (ret) return ret; - ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv); + ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv, cookie); if (ret) goto ref_pin_del; xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); @@ -608,7 +617,7 @@ return ret; ref_pin_del: - dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); return ret; } @@ -640,7 +649,7 @@ dpll->clock_id == pin->clock_id))) ret = -EINVAL; else - ret = __dpll_pin_register(dpll, pin, ops, priv); + ret = __dpll_pin_register(dpll, pin, ops, priv, NULL); mutex_unlock(&dpll_lock); return ret; @@ -649,10 +658,11 @@ static void __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, - const struct dpll_pin_ops *ops, void *priv) + const struct dpll_pin_ops *ops, void *priv, void *cookie) { - dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); - dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv); + ASSERT_DPLL_PIN_REGISTERED(pin); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); + dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv, cookie); if (xa_empty(&pin->dpll_refs)) xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); } @@ -677,7 +687,7 @@ mutex_lock(&dpll_lock); dpll_pin_delete_ntf(pin); - __dpll_pin_unregister(dpll, pin, ops, priv); + __dpll_pin_unregister(dpll, pin, ops, priv, NULL); mutex_unlock(&dpll_lock); } EXPORT_SYMBOL_GPL(dpll_pin_unregister); @@ -713,12 +723,12 @@ return -EINVAL; mutex_lock(&dpll_lock); - ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv); + ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv, pin); if (ret) goto unlock; refcount_inc(&pin->refcount); xa_for_each(&parent->dpll_refs, i, ref) { - ret = __dpll_pin_register(ref->dpll, pin, ops, priv); + ret = __dpll_pin_register(ref->dpll, pin, ops, priv, parent); if (ret) { stop = i; goto dpll_unregister; @@ -732,11 +742,12 @@ dpll_unregister: xa_for_each(&parent->dpll_refs, i, ref) if (i < stop) { - __dpll_pin_unregister(ref->dpll, pin, ops, priv); + __dpll_pin_unregister(ref->dpll, pin, ops, priv, + parent); dpll_pin_delete_ntf(pin); } refcount_dec(&pin->refcount); - dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); unlock: mutex_unlock(&dpll_lock); return ret; @@ -761,10 +772,10 @@ mutex_lock(&dpll_lock); dpll_pin_delete_ntf(pin); - dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); refcount_dec(&pin->refcount); xa_for_each(&pin->dpll_refs, i, ref) - __dpll_pin_unregister(ref->dpll, pin, ops, priv); + __dpll_pin_unregister(ref->dpll, pin, ops, priv, parent); mutex_unlock(&dpll_lock); } EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); --- linux-xilinx-6.8.0.orig/drivers/edac/Kconfig +++ linux-xilinx-6.8.0/drivers/edac/Kconfig @@ -573,4 +573,20 @@ for debugging purposes. +config EDAC_XILINX_XILSEM + tristate "Xilinx Versal XilSEM Controller" + depends on ARCH_ZYNQMP && ZYNQMP_FIRMWARE + help + Support for handling error events on the Xilinx Versal Xilsem + controller. + + Xilinx Versal Soft Error Mitigation (XilSEM) is part of the + Platform Loader and Manager (PLM) which is loaded into and runs on the + Platform Management Controller (PMC). XilSEM is responsible for detecting + and optionally correcting soft errors in Configuration Memory of Versal. + Whenever an error is detected, be it correctable or uncorrectable, XilSEM + reports the errors to user application. + This driver is responsible for handling the reported correctable and + uncorrectable errors. + endif # EDAC --- linux-xilinx-6.8.0.orig/drivers/edac/Makefile +++ linux-xilinx-6.8.0/drivers/edac/Makefile @@ -83,6 +83,7 @@ obj-$(CONFIG_EDAC_QCOM) += qcom_edac.o obj-$(CONFIG_EDAC_ASPEED) += aspeed_edac.o obj-$(CONFIG_EDAC_BLUEFIELD) += bluefield_edac.o +obj-$(CONFIG_EDAC_XILINX_XILSEM) += xilinx_xilsem_edac.o obj-$(CONFIG_EDAC_DMC520) += dmc520_edac.o obj-$(CONFIG_EDAC_NPCM) += npcm_edac.o obj-$(CONFIG_EDAC_ZYNQMP) += zynqmp_edac.o --- linux-xilinx-6.8.0.orig/drivers/edac/amd64_edac.c +++ linux-xilinx-6.8.0/drivers/edac/amd64_edac.c @@ -80,7 +80,7 @@ amd64_warn("%s: error reading F%dx%03x.\n", func, PCI_FUNC(pdev->devfn), offset); - return err; + return pcibios_err_to_errno(err); } int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset, @@ -93,7 +93,7 @@ amd64_warn("%s: error writing to F%dx%03x.\n", func, PCI_FUNC(pdev->devfn), offset); - return err; + return pcibios_err_to_errno(err); } /* @@ -1024,8 +1024,10 @@ } ret = pci_read_config_dword(pdev, REG_LOCAL_NODE_TYPE_MAP, &tmp); - if (ret) + if (ret) { + ret = pcibios_err_to_errno(ret); goto out; + } gpu_node_map.node_count = FIELD_GET(LNTM_NODE_COUNT, tmp); gpu_node_map.base_node_id = FIELD_GET(LNTM_BASE_NODE_ID, tmp); --- linux-xilinx-6.8.0.orig/drivers/edac/igen6_edac.c +++ linux-xilinx-6.8.0/drivers/edac/igen6_edac.c @@ -798,7 +798,7 @@ rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd); if (rc) - return rc; + return pcibios_err_to_errno(rc); if (enable) errcmd |= ERRCMD_CE | ERRSTS_UE; @@ -807,7 +807,7 @@ rc = pci_write_config_word(imc->pdev, ERRCMD_OFFSET, errcmd); if (rc) - return rc; + return pcibios_err_to_errno(rc); return 0; } --- linux-xilinx-6.8.0.orig/drivers/edac/skx_common.c +++ linux-xilinx-6.8.0/drivers/edac/skx_common.c @@ -648,7 +648,7 @@ memset(&res, 0, sizeof(res)); res.mce = mce; res.addr = mce->addr & MCI_ADDR_PHYSADDR; - if (!pfn_to_online_page(res.addr >> PAGE_SHIFT)) { + if (!pfn_to_online_page(res.addr >> PAGE_SHIFT) && !arch_is_platform_page(res.addr)) { pr_err("Invalid address 0x%llx in IA32_MC%d_ADDR\n", mce->addr, mce->bank); return NOTIFY_DONE; } --- linux-xilinx-6.8.0.orig/drivers/edac/synopsys_edac.c +++ linux-xilinx-6.8.0/drivers/edac/synopsys_edac.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -334,6 +335,7 @@ * @get_mtype: Get mtype. * @get_dtype: Get dtype. * @get_ecc_state: Get ECC state. + * @get_mem_info: Get EDAC memory info * @quirks: To differentiate IPs. */ struct synps_platform_data { @@ -341,6 +343,9 @@ enum mem_type (*get_mtype)(const void __iomem *base); enum dev_type (*get_dtype)(const void __iomem *base); bool (*get_ecc_state)(void __iomem *base); +#ifdef CONFIG_EDAC_DEBUG + u64 (*get_mem_info)(struct synps_edac_priv *priv); +#endif int quirks; }; @@ -399,6 +404,25 @@ return 0; } +#ifdef CONFIG_EDAC_DEBUG +/** + * zynqmp_get_mem_info - Get the current memory info. + * @priv: DDR memory controller private instance data. + * + * Return: host interface address. + */ +static u64 zynqmp_get_mem_info(struct synps_edac_priv *priv) +{ + u64 hif_addr = 0, linear_addr; + + linear_addr = priv->poison_addr; + if (linear_addr >= SZ_32G) + linear_addr = linear_addr - SZ_32G + SZ_2G; + hif_addr = linear_addr >> 3; + return hif_addr; +} +#endif + /** * zynqmp_get_error_info - Get the current ECC error info. * @priv: DDR memory controller private instance data. @@ -899,6 +923,9 @@ .get_mtype = zynqmp_get_mtype, .get_dtype = zynqmp_get_dtype, .get_ecc_state = zynqmp_get_ecc_state, +#ifdef CONFIG_EDAC_DEBUG + .get_mem_info = zynqmp_get_mem_info, +#endif .quirks = (DDR_ECC_INTR_SUPPORT #ifdef CONFIG_EDAC_DEBUG | DDR_ECC_DATA_POISON_SUPPORT @@ -952,10 +979,16 @@ static void ddr_poison_setup(struct synps_edac_priv *priv) { int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval; + const struct synps_platform_data *p_data; int index; ulong hif_addr = 0; - hif_addr = priv->poison_addr >> 3; + p_data = priv->p_data; + + if (p_data->get_mem_info) + hif_addr = p_data->get_mem_info(priv); + else + hif_addr = priv->poison_addr >> 3; for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) { if (priv->row_shift[index]) --- linux-xilinx-6.8.0.orig/drivers/edac/versal_edac.c +++ linux-xilinx-6.8.0/drivers/edac/versal_edac.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "edac_module.h" @@ -42,8 +43,11 @@ #define ECCW0_FLIP_CTRL 0x109C #define ECCW0_FLIP0_OFFSET 0x10A0 +#define ECCW0_FLIP0_BITS 31 +#define ECCW0_FLIP1_OFFSET 0x10A4 #define ECCW1_FLIP_CTRL 0x10AC #define ECCW1_FLIP0_OFFSET 0x10B0 +#define ECCW1_FLIP1_OFFSET 0x10B4 #define ECCR0_CERR_STAT_OFFSET 0x10BC #define ECCR0_CE_ADDR_LO_OFFSET 0x10C0 #define ECCR0_CE_ADDR_HI_OFFSET 0x10C4 @@ -116,9 +120,6 @@ #define XDDR_BUS_WIDTH_32 1 #define XDDR_BUS_WIDTH_16 2 -#define ECC_CEPOISON_MASK 0x1 -#define ECC_UEPOISON_MASK 0x3 - #define XDDR_MAX_ROW_CNT 18 #define XDDR_MAX_COL_CNT 10 #define XDDR_MAX_RANK_CNT 2 @@ -133,6 +134,7 @@ * https://docs.xilinx.com/r/en-US/am012-versal-register-reference/PCSR_LOCK-XRAM_SLCR-Register */ #define PCSR_UNLOCK_VAL 0xF9E8D7C6 +#define PCSR_LOCK_VAL 1 #define XDDR_ERR_TYPE_CE 0 #define XDDR_ERR_TYPE_UE 1 @@ -142,6 +144,9 @@ #define XILINX_DRAM_SIZE_12G 3 #define XILINX_DRAM_SIZE_16G 4 #define XILINX_DRAM_SIZE_32G 5 +#define NUM_UE_BITPOS 2 +#define NUM_ECC_BITS 72 +#define DATA_BITS 64 /** * struct ecc_error_info - ECC error log information. @@ -243,6 +248,72 @@ #endif }; +static int rowa[] = { 0x7, 0xB, 0x13, 0x23, 0x43, 0x83, 0xD, 0x15, + 0x25, 0x45, 0x85, 0x19, 0x29, 0x49, 0x89, 0x31, + 0x51, 0x91, 0x61, 0xa1, 0xc1, 0x0e, 0x16, 0x26, + 0x46, 0x86, 0x1a, 0x2a, 0x4a, 0x8a, 0x32, 0x52, + 0x92, 0x62, 0xa2, 0xc2, 0x1c, 0x2c, 0x4c, 0x8c, + 0x34, 0x54, 0x94, 0x64, 0xa4, 0xc4, 0x38, 0x58, + 0x98, 0x68, 0xa8, 0xc8, 0x70, 0xB0, 0xD0, 0xE0, + 0x1f, 0x2f, 0x4f, 0x8f, 0x37, 0x57, 0x97, 0x67, + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + +/* + * Report the bit that was corrupted in the CE errors + * + * The function takes the data and the parity as inputs. + * It derive the corrupted bit from a fixed H Matrix and the data + * and parity. + * + */ +static void calculate_ce_bit_value(u32 eccr0_corr_err_data_hi, u32 regval, u32 parity) +{ + u8 rows[NUM_ECC_BITS] = {0}; + u8 bit, xor[BITS_PER_BYTE], match = 0; + bool field, prev; + u64 data; + int i, j; + + data = (u64)eccr0_corr_err_data_hi << 32; + data |= regval; + + for (i = 0 ; i < DATA_BITS; i++) { + if (data & BIT(i)) + rows[i] = rowa[i]; + } + + for (i = DATA_BITS ; i < NUM_ECC_BITS; i++) { + j = i - DATA_BITS; + if (parity & BIT(j)) + rows[i] = rowa[i]; + } + + for (j = 0 ; j < BITS_PER_BYTE; j++) { + bit = rows[0] & BIT(j); + prev = !!bit; + + for (i = 1 ; i < NUM_ECC_BITS; i++) { + bit = rows[i] & BIT(j); + field = !!bit; + if (field != prev) + prev = true; + else + prev = false; + } + xor[j] = prev; + } + + for (j = 0 ; j < BITS_PER_BYTE; j++) + match |= xor[j] << j; + + for (i = 0 ; i < NUM_ECC_BITS; i++) { + if (match == rowa[i]) { + edac_dbg(2, "bit found is 0x%08X\n", i); + return; + } + } +} + static void get_ce_error_info(struct edac_priv *priv) { void __iomem *ddrmc_base; @@ -269,6 +340,15 @@ p->ceinfo[1].i = regval | reghi << 32; regval = readl(ddrmc_base + ECCR1_CE_ADDR_HI_OFFSET); + if (IS_ENABLED(CONFIG_EDAC_DEBUG)) { + u32 eccr0_corr_err_data_hi, par; + + par = readl(ddrmc_base + ECCR0_CE_DATA_PAR_OFFSET); + regval = readl(ddrmc_base + ECCR0_CE_DATA_LO_OFFSET); + eccr0_corr_err_data_hi = readl(ddrmc_base + ECCR0_CE_DATA_HI_OFFSET); + calculate_ce_bit_value(eccr0_corr_err_data_hi, regval, par); + } + edac_dbg(2, "ERR DATA: 0x%08X%08X ERR DATA PARITY: 0x%08X\n", readl(ddrmc_base + ECCR1_CE_DATA_LO_OFFSET), readl(ddrmc_base + ECCR1_CE_DATA_HI_OFFSET), @@ -423,7 +503,7 @@ convert_to_physical(priv, pinf), pinf.burstpos); edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, - priv->ce_cnt, 0, 0, 0, 0, 0, -1, + 1, 0, 0, 0, 0, 0, -1, priv->message, ""); } @@ -436,7 +516,7 @@ convert_to_physical(priv, pinf), pinf.burstpos); edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, - priv->ue_cnt, 0, 0, 0, 0, 0, -1, + 1, 0, 0, 0, 0, 0, -1, priv->message, ""); } @@ -462,9 +542,9 @@ regval = readl(priv->ddrmc_baseaddr + XDDR_ISR_OFFSET); - if (payload[EVENT] == XPM_EVENT_ERROR_MASK_DDRMC_CR) + if (payload[EVENT] == XPM_VERSAL_EVENT_ERROR_MASK_DDRMC_CR) p->error_type = XDDR_ERR_TYPE_CE; - if (payload[EVENT] == XPM_EVENT_ERROR_MASK_DDRMC_NCR) + if (payload[EVENT] == XPM_VERSAL_EVENT_ERROR_MASK_DDRMC_NCR) p->error_type = XDDR_ERR_TYPE_UE; if (get_error_info(priv)) @@ -479,7 +559,7 @@ writel(regval, priv->ddrmc_baseaddr + XDDR_ISR_OFFSET); /* Lock the PCSR registers */ - writel(1, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_LOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); edac_dbg(3, "Total error count CE %d UE %d\n", priv->ce_cnt, priv->ue_cnt); } @@ -650,7 +730,7 @@ writel(XDDR_IRQ_UE_MASK, priv->ddrmc_baseaddr + XDDR_IRQ1_EN_OFFSET); /* Lock the PCSR registers */ - writel(1, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_LOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); } static void disable_intr(struct edac_priv *priv) @@ -663,7 +743,7 @@ priv->ddrmc_baseaddr + XDDR_IRQ_DIS_OFFSET); /* Lock the PCSR registers */ - writel(1, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_LOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); } #define to_mci(k) container_of(k, struct mem_ctl_info, dev) @@ -734,38 +814,63 @@ writel(regval, priv->ddrmc_noc_baseaddr + XDDR_NOC_REG_ADEC15_OFFSET); } -static ssize_t xddr_inject_data_poison_store(struct mem_ctl_info *mci, - const char __user *data) +static void xddr_inject_data_ce_store(struct mem_ctl_info *mci, u8 ce_bitpos) { + u32 ecc0_flip0, ecc1_flip0, ecc0_flip1, ecc1_flip1; struct edac_priv *priv = mci->pvt_info; - writel(0, priv->ddrmc_baseaddr + ECCW0_FLIP0_OFFSET); - writel(0, priv->ddrmc_baseaddr + ECCW1_FLIP0_OFFSET); - - if (strncmp(data, "CE", 2) == 0) { - writel(ECC_CEPOISON_MASK, priv->ddrmc_baseaddr + - ECCW0_FLIP0_OFFSET); - writel(ECC_CEPOISON_MASK, priv->ddrmc_baseaddr + - ECCW1_FLIP0_OFFSET); + if (ce_bitpos <= ECCW0_FLIP0_BITS) { + ecc0_flip0 = BIT(ce_bitpos); + ecc1_flip0 = BIT(ce_bitpos); + ecc0_flip1 = 0; + ecc1_flip1 = 0; } else { - writel(ECC_UEPOISON_MASK, priv->ddrmc_baseaddr + - ECCW0_FLIP0_OFFSET); - writel(ECC_UEPOISON_MASK, priv->ddrmc_baseaddr + - ECCW1_FLIP0_OFFSET); + ce_bitpos = ce_bitpos - ECCW0_FLIP0_BITS - 1; + ecc0_flip1 = BIT(ce_bitpos); + ecc1_flip1 = BIT(ce_bitpos); + ecc0_flip0 = 0; + ecc1_flip0 = 0; } - /* Lock the PCSR registers */ - writel(1, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); - - return 0; + writel(ecc0_flip0, priv->ddrmc_baseaddr + ECCW0_FLIP0_OFFSET); + writel(ecc1_flip0, priv->ddrmc_baseaddr + ECCW1_FLIP0_OFFSET); + writel(ecc0_flip1, priv->ddrmc_baseaddr + ECCW0_FLIP1_OFFSET); + writel(ecc1_flip1, priv->ddrmc_baseaddr + ECCW1_FLIP1_OFFSET); } -static ssize_t inject_data_poison_store(struct file *file, const char __user *data, - size_t count, loff_t *ppos) +/* + * To inject a correctable error, the following steps are needed: + * + * - Write the correctable error bit position value: + * echo > /sys/kernel/debug/edac//inject_ce + * + * poison_setup() derives the row, column, bank, group and rank and + * writes to the ADEC registers based on the address given by the user. + * + * The ADEC12 and ADEC13 are mask registers; write 0 to make sure default + * configuration is there and no addresses are masked. + * + * The row, column, bank, group and rank registers are written to the + * match ADEC bit to generate errors at the particular address. ADEC14 + * and ADEC15 have the match bits. + * + * xddr_inject_data_ce_store() updates the ECC FLIP registers with the + * bits to be corrupted based on the bit position given by the user. + * + * Upon doing a read to the address the errors are injected. + */ +static ssize_t inject_data_ce_store(struct file *file, const char __user *data, + size_t count, loff_t *ppos) { struct device *dev = file->private_data; struct mem_ctl_info *mci = to_mci(dev); struct edac_priv *priv = mci->pvt_info; + u8 ce_bitpos; + int ret; + + ret = kstrtou8_from_user(data, count, 0, &ce_bitpos); + if (ret) + return ret; /* Unlock the PCSR registers */ writel(PCSR_UNLOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); @@ -773,17 +878,113 @@ poison_setup(priv); + xddr_inject_data_ce_store(mci, ce_bitpos); + ret = count; + /* Lock the PCSR registers */ - writel(1, priv->ddrmc_noc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_LOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_LOCK_VAL, priv->ddrmc_noc_baseaddr + XDDR_PCSR_OFFSET); + + return ret; +} + +static const struct file_operations xddr_inject_ce_fops = { + .open = simple_open, + .write = inject_data_ce_store, + .llseek = generic_file_llseek, +}; + +static void xddr_inject_data_ue_store(struct mem_ctl_info *mci, u32 val0, u32 val1) +{ + struct edac_priv *priv = mci->pvt_info; + + writel(val0, priv->ddrmc_baseaddr + ECCW0_FLIP0_OFFSET); + writel(val0, priv->ddrmc_baseaddr + ECCW0_FLIP1_OFFSET); + writel(val1, priv->ddrmc_baseaddr + ECCW1_FLIP1_OFFSET); + writel(val1, priv->ddrmc_baseaddr + ECCW1_FLIP1_OFFSET); +} + +/* + * To inject an uncorrectable error, the following steps are needed: + * echo > /sys/kernel/debug/edac//inject_ue + * + * poison_setup() derives the row, column, bank, group and rank and + * writes to the ADEC registers based on the address given by the user. + * + * The ADEC12 and ADEC13 are mask registers; write 0 so that none of the + * addresses are masked. The row, column, bank, group and rank registers + * are written to the match ADEC bit to generate errors at the + * particular address. ADEC14 and ADEC15 have the match bits. + * + * xddr_inject_data_ue_store() updates the ECC FLIP registers with the + * bits to be corrupted based on the bit position given by the user. For + * uncorrectable errors + * 2 bit errors are injected. + * + * Upon doing a read to the address the errors are injected. + */ +static ssize_t inject_data_ue_store(struct file *file, const char __user *data, + size_t count, loff_t *ppos) +{ + struct device *dev = file->private_data; + struct mem_ctl_info *mci = to_mci(dev); + struct edac_priv *priv = mci->pvt_info; + char buf[6], *pbuf, *token[2]; + u32 val0 = 0, val1 = 0; + u8 len, ue0, ue1; + int i, ret; + + len = min_t(size_t, count, sizeof(buf)); + if (copy_from_user(buf, data, len)) + return -EFAULT; + + buf[len] = '\0'; + pbuf = &buf[0]; + for (i = 0; i < NUM_UE_BITPOS; i++) + token[i] = strsep(&pbuf, ","); + + if (!token[0] || !token[1]) + return -EFAULT; + + ret = kstrtou8(token[0], 0, &ue0); + if (ret) + return ret; + + ret = kstrtou8(token[1], 0, &ue1); + if (ret) + return ret; - xddr_inject_data_poison_store(mci, data); + if (ue0 <= ECCW0_FLIP0_BITS) { + val0 = BIT(ue0); + } else { + ue0 = ue0 - ECCW0_FLIP0_BITS - 1; + val1 = BIT(ue0); + } + + if (ue1 <= ECCW0_FLIP0_BITS) { + val0 |= BIT(ue1); + } else { + ue1 = ue1 - ECCW0_FLIP0_BITS - 1; + val1 |= BIT(ue1); + } + + /* Unlock the PCSR registers */ + writel(PCSR_UNLOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_UNLOCK_VAL, priv->ddrmc_noc_baseaddr + XDDR_PCSR_OFFSET); + poison_setup(priv); + + xddr_inject_data_ue_store(mci, val0, val1); + + /* Lock the PCSR registers */ + writel(PCSR_LOCK_VAL, priv->ddrmc_noc_baseaddr + XDDR_PCSR_OFFSET); + writel(PCSR_LOCK_VAL, priv->ddrmc_baseaddr + XDDR_PCSR_OFFSET); return count; } -static const struct file_operations xddr_inject_enable_fops = { +static const struct file_operations xddr_inject_ue_fops = { .open = simple_open, - .write = inject_data_poison_store, + .write = inject_data_ue_store, .llseek = generic_file_llseek, }; @@ -795,8 +996,17 @@ if (!priv->debugfs) return; - edac_debugfs_create_file("inject_error", 0200, priv->debugfs, - &mci->dev, &xddr_inject_enable_fops); + if (!edac_debugfs_create_file("inject_ce", 0200, priv->debugfs, + &mci->dev, &xddr_inject_ce_fops)) { + debugfs_remove_recursive(priv->debugfs); + return; + } + + if (!edac_debugfs_create_file("inject_ue", 0200, priv->debugfs, + &mci->dev, &xddr_inject_ue_fops)) { + debugfs_remove_recursive(priv->debugfs); + return; + } debugfs_create_x64("address", 0600, priv->debugfs, &priv->err_inject_addr); mci->debugfs = priv->debugfs; @@ -1006,8 +1216,8 @@ } rc = xlnx_register_event(PM_NOTIFY_CB, VERSAL_EVENT_ERROR_PMC_ERR1, - XPM_EVENT_ERROR_MASK_DDRMC_CR | XPM_EVENT_ERROR_MASK_DDRMC_NCR | - XPM_EVENT_ERROR_MASK_NOC_CR | XPM_EVENT_ERROR_MASK_NOC_NCR, + XPM_VERSAL_EVENT_ERROR_MASK_DDRMC_CR | + XPM_VERSAL_EVENT_ERROR_MASK_DDRMC_NCR, false, err_callback, mci); if (rc) { if (rc == -EACCES) @@ -1043,10 +1253,8 @@ #endif xlnx_unregister_event(PM_NOTIFY_CB, VERSAL_EVENT_ERROR_PMC_ERR1, - XPM_EVENT_ERROR_MASK_DDRMC_CR | - XPM_EVENT_ERROR_MASK_NOC_CR | - XPM_EVENT_ERROR_MASK_NOC_NCR | - XPM_EVENT_ERROR_MASK_DDRMC_NCR, err_callback, mci); + XPM_VERSAL_EVENT_ERROR_MASK_DDRMC_CR | + XPM_VERSAL_EVENT_ERROR_MASK_DDRMC_NCR, err_callback, mci); edac_mc_del_mc(&pdev->dev); edac_mc_free(mci); --- linux-xilinx-6.8.0.orig/drivers/edac/xilinx_xilsem_edac.c +++ linux-xilinx-6.8.0/drivers/edac/xilinx_xilsem_edac.c @@ -0,0 +1,781 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "edac_module.h" + +#define VERSAL_XILSEM_EDAC_MSG_SIZE 256 +#define VERSAL_XILSEM_EDAC_STRNG "versal_xilsem" +#define EDAC_DEVICE "Xilsem" + +/* XilSem CE Error log count */ +#define XILSEM_MAX_CE_LOG_CNT 0x07 + +/* XilSem_CRAM scan error info registers */ +#define CRAM_STS_INFO_OFFSET 0x34 +#define CRAM_CE_ADDRL0_OFFSET 0x38 +#define CRAM_CE_ADDRH0_OFFSET 0x3C +#define CRAM_CE_COUNT_OFFSET 0x70 + +/* XilSem_NPI_Scan uncorrectable error info registers */ +#define NPI_SCAN_COUNT 0x24 +#define NPI_SCAN_HB_COUNT 0x28 +#define NPI_ERR0_INFO_OFFSET 0x2C +#define NPI_ERR1_INFO_OFFSET 0x30 + +/* XilSem bit masks for extracting error details */ +#define CRAM_ERR_ROW_MASK GENMASK(26, 23) +#define CRAM_ERR_BIT_MASK GENMASK(22, 16) +#define CRAM_ERR_QWRD_MASK GENMASK(27, 23) +#define CRAM_ERR_FRAME_MASK GENMASK(22, 0) + +enum xsem_cmd_id { + CRAM_INIT_SCAN = 1, /* To initialize CRAM scan */ + CRAM_START_SCAN = 2, /* To start CRAM scan */ + CRAM_STOP_SCAN = 3, /* To stop CRAM scan */ + CRAM_ERR_INJECT = 4, /* To inject CRAM error */ + NPI_START_SCAN = 5, /* To start NPI scan */ + NPI_STOP_SCAN = 6, /* To stop NPI scan */ + NPI_ERR_INJECT = 7, /* To inject NPI error */ +}; + +/* XilSem Module IDs */ +#define CRAM_MOD_ID 0x1 +#define NPI_MOD_ID 0x2 + +/** + * struct ecc_error_info - ECC error log information + * @status: CRAM/NPI scan error status + * @data0: Checksum of the error descriptor + * @data1: Index of the error descriptor + * @frame_addr: Frame location at which error occurred + * @block_type: Block type + * @row_id: Row number + * @bit_loc: Bit position in the Qword + * @qword: Qword location in the frame + */ +struct ecc_error_info { + u32 status; + u32 data0; + u32 data1; + u32 frame_addr; + u8 block_type; + u8 row_id; + u8 bit_loc; + u8 qword; +}; + +/** + * struct xsem_error_status - ECC status information to report + * @ce_cnt: Correctable error count + * @ue_cnt: Uncorrectable error count + * @ceinfo: Correctable error log information + * @ueinfo: Uncorrectable error log information + */ +struct xsem_error_status { + u32 ce_cnt; + u32 ue_cnt; + struct ecc_error_info ceinfo; + struct ecc_error_info ueinfo; +}; + +/** + * struct xsem_edac_priv - Xilsem private instance data + * @baseaddr: Base address of the XilSem PLM RTCA module + * @scan_ctrl_status: Buffer for scan ctrl commands + * @cram_errinj_status: Buffer for CRAM error injection + * @cram_frame_ecc: Buffer for CRAM frame ECC + * @xilsem_status: Buffer for CRAM & NPI status + * @sw_event_node_id: Error event node Id + * @xilsem_cfg: Buffer for CRAM & NPI configuration + * @cram_ce_mask: Event bit mask for CRAM correctable error + * @cram_ue_mask: Event bit mask for CRAM uncorrectable error + * @npi_ue_mask: Event bit mask for NPI uncorrectable error + * @ce_cnt: Correctable Error count + * @ue_cnt: Uncorrectable Error count + */ +struct xsem_edac_priv { + void __iomem *baseaddr; + u32 scan_ctrl_status[2]; + u32 cram_errinj_status[2]; + u32 cram_frame_ecc[4]; + u32 xilsem_status[4]; + u32 sw_event_node_id; + u32 xilsem_cfg[4]; + u32 cram_ce_mask; + u32 cram_ue_mask; + u32 npi_ue_mask; + u32 ce_cnt; + u32 ue_cnt; +}; + +/** + * xsem_scan_control_show - Shows scan control operation status + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * + * Shows the scan control operations status + * Return: Number of bytes copied. + */ +static ssize_t xsem_scan_control_show(struct edac_device_ctl_info + *dci, char *data) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + + return sprintf(data, "[0x%x][0x%x]\n\r", + priv->scan_ctrl_status[0], priv->scan_ctrl_status[1]); +} + +/** + * xsem_scan_control_store - Set scan control operation + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * @count: read the size bytes from buffer + * + * User-space interface for doing Xilsem scan operations + * + * To control scan operations + * echo > /sys/devices/system/edac/versal_xilsem/xsem_scan_control + * Usage: + * echo 1 > /sys/devices/system/edac/versal_xilsem/xsem_scan_control + * + * Set scan control (init, start, stop) operations + * Return: count argument if request succeeds, else error code + */ +static ssize_t xsem_scan_control_store(struct edac_device_ctl_info *dci, + const char *data, size_t count) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + u32 cmd; + int ret; + + if (!data) + return -EFAULT; + + if (kstrtouint(data, 0, &cmd)) + return -EINVAL; + + if (cmd < CRAM_INIT_SCAN || cmd > NPI_ERR_INJECT || + cmd == CRAM_ERR_INJECT) + return -EINVAL; + + ret = zynqmp_pm_xilsem_cntrl_ops(cmd, priv->scan_ctrl_status); + if (ret) + return ret; + + return count; +} + +/** + * xsem_cram_injecterr_show - Shows CRAM error injection status + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * + * Shows CRAM error injection status + * Return: Number of bytes copied. + */ +static ssize_t xsem_cram_injecterr_show(struct edac_device_ctl_info *dci, char *data) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + + return sprintf(data, "[0x%x][0x%x]\n\r", priv->cram_errinj_status[0], + priv->cram_errinj_status[1]); +} + +/** + * xsem_cram_injecterr_store - Start error injection + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * @count: read the size bytes from buffer + * + * User-space interface for doing CRAM error injection + * + * To inject error + * echo > /sys/devices/system/edac/versal_xilsem/xsem_cram_injecterr + * Usage: + * echo 1 2 2 1 > /sys/devices/system/edac/versal_xilsem/xsem_cram_injecterr + * + * Start error injection + * Return: count argument if request succeeds, else error code + */ +static ssize_t xsem_cram_injecterr_store(struct edac_device_ctl_info *dci, + const char *data, size_t count) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + char *kern_buff, *inbuf, *tok; + u32 row, frame, qword, bitloc; + int ret; + + kern_buff = kzalloc(count, GFP_KERNEL); + if (!kern_buff) + return -ENOMEM; + + strscpy(kern_buff, data, count); + + inbuf = kern_buff; + + /* Read Frame number */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + + ret = kstrtouint(tok, 0, &frame); + if (ret) { + ret = -EFAULT; + goto err; + } + + /* Read Qword number */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + + ret = kstrtouint(tok, 0, &qword); + if (ret) { + ret = -EFAULT; + goto err; + } + + /* Read Bit location */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + + ret = kstrtouint(tok, 0, &bitloc); + if (ret) { + ret = -EFAULT; + goto err; + } + + /* Read Row number */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + + ret = kstrtouint(tok, 0, &row); + if (ret) { + ret = -EFAULT; + goto err; + } + + ret = zynqmp_pm_xilsem_cram_errinj(frame, qword, bitloc, row, + priv->cram_errinj_status); +err: + kfree(kern_buff); + + if (ret) + return ret; + + return count; +} + +/** + * xsem_cram_framecc_read_show - Shows CRAM Frame ECC + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * + * Shows CRAM Frame ECC value + * Return: Number of bytes copied. + */ +static ssize_t xsem_cram_framecc_read_show(struct edac_device_ctl_info *dci, + char *data) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + + return sprintf(data, "[0x%x][0x%x][0x%x][0x%x]\n\r", + priv->cram_frame_ecc[0], priv->cram_frame_ecc[1], + priv->cram_frame_ecc[2], priv->cram_frame_ecc[3]); +} + +/** + * xsem_cram_framecc_read_store - Read CRAM Frame ECC + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * @count: read the size bytes from buffer + * + * User-space interface for reading CRAM frame ECC + * + * To read ecc + * echo > /sys/devices/system/edac/versal_xilsem/xsem_cram_framecc_read + * Usage: + * echo 1 2 > /sys/devices/system/edac/versal_xilsem/xsem_cram_framecc_read + * + * Read CRAM Frame ECC + * Return: count argument if request succeeds, else error code + */ +static ssize_t xsem_cram_framecc_read_store(struct edac_device_ctl_info *dci, + const char *data, size_t count) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + char *kern_buff, *inbuf, *tok; + u32 frameaddr, row; + int ret; + + kern_buff = kzalloc(count, GFP_KERNEL); + if (!kern_buff) + return -ENOMEM; + + strscpy(kern_buff, data, count); + + inbuf = kern_buff; + + /* Read Frame address */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + + ret = kstrtouint(tok, 0, &frameaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + + /* Read Row number */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + + ret = kstrtouint(tok, 0, &row); + if (ret) { + ret = -EFAULT; + goto err; + } + + ret = zynqmp_pm_xilsem_cram_readecc(frameaddr, row, priv->cram_frame_ecc); +err: + kfree(kern_buff); + + if (ret) + return ret; + + return count; +} + +/** + * xsem_read_status_show - Shows CRAM & NPI scan status + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * + * Shows CRAM & NPI scan status + * Return: Number of bytes copied. + */ +static ssize_t xsem_read_status_show(struct edac_device_ctl_info *dci, char *data) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + + return sprintf(data, "[0x%x][0x%x][0x%x]\n\r", + priv->xilsem_status[0], priv->xilsem_status[1], + priv->xilsem_status[2]); +} + +/** + * xsem_read_status_store - Read CRAM & NPI scan status + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * @count: read the size bytes from buffer + * + * User-space interface for reading Xilsem status + * + * To read status + * echo > /sys/devices/system/edac/versal_xilsem/xsem_read_status + * Usage: + * echo 1 > /sys/devices/system/edac/versal_xilsem/xsem_read_status + * + * Read CRAM & NPI scan status + * Return: count argument if rea succeeds, else error code + */ +static ssize_t xsem_read_status_store(struct edac_device_ctl_info *dci, + const char *data, size_t count) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + u32 module; + + if (!data) + return -EFAULT; + + if (kstrtouint(data, 0, &module)) + return -EINVAL; + + if (module == CRAM_MOD_ID) { + priv->xilsem_status[0] = readl(priv->baseaddr + CRAM_STS_INFO_OFFSET); + priv->xilsem_status[1] = readl(priv->baseaddr + CRAM_CE_COUNT_OFFSET); + priv->xilsem_status[2] = 0; + } else if (module == NPI_MOD_ID) { + priv->xilsem_status[0] = readl(priv->baseaddr); + priv->xilsem_status[1] = readl(priv->baseaddr + NPI_SCAN_COUNT); + priv->xilsem_status[2] = readl(priv->baseaddr + NPI_SCAN_HB_COUNT); + } else { + edac_printk(KERN_ERR, EDAC_DEVICE, "Invalid module %d\n", module); + return -EINVAL; + } + + return count; +} + +/** + * xsem_read_config_show - Shows CRAM & NPI configuration + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * + * Shows CRAM & NPI configuration + * Return: Number of bytes copied. + */ +static ssize_t xsem_read_config_show(struct edac_device_ctl_info *dci, char *data) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + + return sprintf(data, "[0x%x][0x%x][0x%x][0x%x]\n\r", + priv->xilsem_cfg[0], priv->xilsem_cfg[1], + priv->xilsem_cfg[2], priv->xilsem_cfg[3]); +} + +/** + * xsem_read_config_store - Read CRAM & NPI configuration + * @dci: Pointer to the edac device struct + * @data: Pointer to user data + * @count: read the size bytes from buffer + * + * User-space interface for reading Xilsem configuration + * + * To read configuration + * echo 1 > /sys/devices/system/edac/versal_xilsem/xsem_read_config + * Usage: + * echo 1 > /sys/devices/system/edac/versal_xilsem/xsem_read_config + * + * Read CRAM & NPI configuration + * Return: count argument if request succeeds, else error code + */ +static ssize_t xsem_read_config_store(struct edac_device_ctl_info *dci, + const char *data, size_t count) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + int ret; + + if (!data) + return -EFAULT; + + ret = zynqmp_pm_xilsem_read_cfg(priv->xilsem_cfg); + + if (ret) + return ret; + + return count; +} + +/** + * xsem_handle_error - Handle XilSem error types CE and UE + * @dci: Pointer to the edac device controller instance + * @p: Pointer to the xilsem error status structure + * + * Handles the correctable and uncorrectable error. + */ +static void xsem_handle_error(struct edac_device_ctl_info *dci, struct xsem_error_status *p) +{ + struct ecc_error_info *pinf; + char message[VERSAL_XILSEM_EDAC_MSG_SIZE]; + + if (p->ce_cnt) { + pinf = &p->ceinfo; + snprintf(message, VERSAL_XILSEM_EDAC_MSG_SIZE, + "\n\rXILSEM CRAM error type :%s\n\r" + "\nFrame_Addr: [0x%X]\t Row_num: [0x%X]\t Bit_loc: [0x%X]\t Qword: [0x%X]\n\r", + "CE", pinf->frame_addr, pinf->row_id, + pinf->bit_loc, pinf->qword); + edac_device_handle_ce(dci, 0, 0, message); + } + + if (p->ue_cnt) { + pinf = &p->ueinfo; + snprintf(message, VERSAL_XILSEM_EDAC_MSG_SIZE, + "\n\rXILSEM error type :%s\n\r" + "status: [0x%X]\n\rError_Info0: [0x%X]\n\r" + "Error_Info1: [0x%X]", + "UE", pinf->status, pinf->data0, pinf->data1); + edac_device_handle_ue(dci, 0, 0, message); + } +} + +/** + * xsem_geterror_info - Get the current ecc error info + * @dci: Pointer to the edac device controller instance + * @p: Pointer to the Xilsem error status structure + * @mask: mask indictaes the error type + * + * Determines there is any ecc error or not + */ +static void xsem_geterror_info(struct edac_device_ctl_info *dci, struct xsem_error_status *p, + int mask) +{ + struct xsem_edac_priv *priv = dci->pvt_info; + u32 error_word_0, error_word_1, ce_count; + u8 index; + + if (mask & priv->cram_ce_mask) { + p->ce_cnt++; + + /* Read CRAM total correctable error count */ + ce_count = readl(priv->baseaddr + CRAM_CE_COUNT_OFFSET); + /* Calculate index for error log */ + index = (ce_count % XILSEM_MAX_CE_LOG_CNT); + /* + * Check if addr index is not 0 + * if yes, then decrement index, else set index as last entry + */ + if (index != 0U) { + /* Decrement Index */ + --index; + } else { + /* Set log index to 6 (Max-1) */ + index = (XILSEM_MAX_CE_LOG_CNT - 1); + } + error_word_0 = readl(priv->baseaddr + CRAM_CE_ADDRL0_OFFSET + (index * 8U)); + error_word_1 = readl(priv->baseaddr + CRAM_CE_ADDRH0_OFFSET + (index * 8U)); + + /* Frame is at 22:0 bits of SEM_CRAMERR_ADDRH0 reg */ + p->ceinfo.frame_addr = FIELD_GET(CRAM_ERR_FRAME_MASK, error_word_1); + + /* row is at 26:23 bits of SEM_CRAMERR_ADDRH0 reg */ + p->ceinfo.row_id = FIELD_GET(CRAM_ERR_ROW_MASK, error_word_1); + + /* bit is at 22:16 bits of SEM_CRAMERR_ADDRL0 reg */ + p->ceinfo.bit_loc = FIELD_GET(CRAM_ERR_BIT_MASK, error_word_0); + + /* Qword is at 27:23 bits of SEM_CRAMERR_ADDRL0 reg */ + p->ceinfo.qword = FIELD_GET(CRAM_ERR_QWRD_MASK, error_word_0); + + /* Read CRAM status */ + p->ceinfo.status = readl(priv->baseaddr + CRAM_STS_INFO_OFFSET); + } else if (mask & priv->cram_ue_mask) { + p->ue_cnt++; + p->ueinfo.data0 = 0; + p->ueinfo.data1 = 0; + p->ueinfo.status = readl(priv->baseaddr + CRAM_STS_INFO_OFFSET); + } else if (mask & priv->npi_ue_mask) { + p->ue_cnt++; + p->ueinfo.data0 = readl(priv->baseaddr + NPI_ERR0_INFO_OFFSET); + p->ueinfo.data1 = readl(priv->baseaddr + NPI_ERR1_INFO_OFFSET); + p->ueinfo.status = readl(priv->baseaddr); + } else { + edac_printk(KERN_ERR, EDAC_DEVICE, "Invalid Event received %d\n", mask); + } +} + +/** + * xsem_err_callback - Handle Correctable and Uncorrectable errors. + * @payload: payload data. + * @data: controller data. + * + * Handles ECC correctable and uncorrectable errors. + */ +static void xsem_err_callback(const u32 *payload, void *data) +{ + struct edac_device_ctl_info *dci = (struct edac_device_ctl_info *)data; + struct xsem_error_status stat; + struct xsem_edac_priv *priv; + int event; + + priv = dci->pvt_info; + memset(&stat, 0, sizeof(stat)); + /* Read payload to get the event type */ + event = payload[2]; + edac_printk(KERN_INFO, EDAC_DEVICE, "Event received %x\n", event); + xsem_geterror_info(dci, &stat, event); + + priv->ce_cnt += stat.ce_cnt; + priv->ue_cnt += stat.ue_cnt; + xsem_handle_error(dci, &stat); +} + +static struct edac_dev_sysfs_attribute xsem_edac_sysfs_attributes[] = { + { + .attr = { + .name = "xsem_scan_control_ops", + .mode = (0644) + }, + .show = xsem_scan_control_show, + .store = xsem_scan_control_store}, + { + .attr = { + .name = "xsem_cram_injecterr", + .mode = (0644) + }, + .show = xsem_cram_injecterr_show, + .store = xsem_cram_injecterr_store}, + { + .attr = { + .name = "xsem_cram_framecc_read", + .mode = (0644) + }, + .show = xsem_cram_framecc_read_show, + .store = xsem_cram_framecc_read_store}, + { + .attr = { + .name = "xsem_read_status", + .mode = (0644) + }, + .show = xsem_read_status_show, + .store = xsem_read_status_store}, + { + .attr = { + .name = "xsem_read_config", + .mode = (0644) + }, + .show = xsem_read_config_show, + .store = xsem_read_config_store}, + { + .attr = {.name = NULL} + } +}; + +/** + * xsem_edac_probe - Check controller and bind driver. + * @pdev: platform device. + * + * Probe a specific controller instance for binding with the driver. + * + * Return: 0 if the controller instance was successfully bound to the + * driver; otherwise, < 0 on error. + */ +static int xsem_edac_probe(struct platform_device *pdev) +{ + struct xsem_edac_priv *priv; + void __iomem *plmrtca_baseaddr; + struct edac_device_ctl_info *dci; + u32 device_sub_family_code; + u32 family_code; + int rc; + + plmrtca_baseaddr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(plmrtca_baseaddr)) + return PTR_ERR(plmrtca_baseaddr); + + dci = edac_device_alloc_ctl_info(sizeof(*priv), VERSAL_XILSEM_EDAC_STRNG, + 1, VERSAL_XILSEM_EDAC_STRNG, 1, 0, NULL, 0, + edac_device_alloc_index()); + if (!dci) { + edac_printk(KERN_ERR, EDAC_DEVICE, "Unable to allocate EDAC device\n"); + return -ENOMEM; + } + + priv = dci->pvt_info; + platform_set_drvdata(pdev, dci); + dci->dev = &pdev->dev; + priv->baseaddr = plmrtca_baseaddr; + dci->mod_name = pdev->dev.driver->name; + dci->ctl_name = VERSAL_XILSEM_EDAC_STRNG; + dci->dev_name = dev_name(&pdev->dev); + + dci->sysfs_attributes = xsem_edac_sysfs_attributes; + rc = edac_device_add_device(dci); + if (rc) + goto free_dev_ctl; + + rc = zynqmp_pm_get_family_info(&family_code, &device_sub_family_code); + if (rc) { + if (rc == -ENODEV) + rc = -EPROBE_DEFER; + goto free_edac_dev; + } + + if (device_sub_family_code == VERSALNET_SUB_FAMILY_CODE) { + priv->sw_event_node_id = VERSAL_NET_EVENT_ERROR_SW_ERR; + priv->cram_ce_mask = XPM_VERSAL_NET_EVENT_ERROR_MASK_XSEM_CRAM_CE; + priv->cram_ue_mask = XPM_VERSAL_NET_EVENT_ERROR_MASK_XSEM_CRAM_UE; + priv->npi_ue_mask = XPM_VERSAL_NET_EVENT_ERROR_MASK_XSEM_NPI_UE; + } else if (device_sub_family_code == VERSAL_SUB_FAMILY_CODE) { + priv->sw_event_node_id = VERSAL_EVENT_ERROR_SW_ERR; + priv->cram_ce_mask = XPM_VERSAL_EVENT_ERROR_MASK_XSEM_CRAM_CE_5; + priv->cram_ue_mask = XPM_VERSAL_EVENT_ERROR_MASK_XSEM_CRAM_UE_6; + priv->npi_ue_mask = XPM_VERSAL_EVENT_ERROR_MASK_XSEM_NPI_UE_7; + } else { + edac_printk(KERN_ERR, EDAC_DEVICE, "Invalid Device Sub family code %d\n", + device_sub_family_code); + } + rc = xlnx_register_event(PM_NOTIFY_CB, priv->sw_event_node_id, + priv->cram_ce_mask | priv->cram_ue_mask | priv->npi_ue_mask, + false, xsem_err_callback, dci); + if (rc) { + if (rc == -EACCES) + rc = -EPROBE_DEFER; + goto free_edac_dev; + } + + edac_printk(KERN_DEBUG, EDAC_DEVICE, "%s success\n", __func__); + return rc; + +free_edac_dev: + edac_device_del_device(&pdev->dev); +free_dev_ctl: + edac_device_free_ctl_info(dci); + + return rc; +} + +/** + * xsem_edac_remove - Unbind driver from controller. + * @pdev: Platform device. + * + * Return: Unconditionally 0 + */ +static int xsem_edac_remove(struct platform_device *pdev) +{ + struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); + struct xsem_edac_priv *priv = dci->pvt_info; + + xlnx_unregister_event(PM_NOTIFY_CB, priv->sw_event_node_id, + priv->cram_ce_mask | priv->cram_ue_mask | priv->npi_ue_mask, + xsem_err_callback, dci); + edac_device_del_device(&pdev->dev); + edac_device_free_ctl_info(dci); + + return 0; +} + +static const struct of_device_id xlnx_xsem_edac_match[] = { + { .compatible = "xlnx,versal-xilsem-edac", }, + { + /* end of table */ + } +}; + +MODULE_DEVICE_TABLE(of, xlnx_xsem_edac_match); + +static struct platform_driver xilinx_xsem_edac_driver = { + .driver = { + .name = "xilinx-xilsem-edac", + .of_match_table = xlnx_xsem_edac_match, + }, + .probe = xsem_edac_probe, + .remove = xsem_edac_remove, +}; + +module_platform_driver(xilinx_xsem_edac_driver); + +MODULE_AUTHOR("Advanced Micro Devices, Inc."); +MODULE_DESCRIPTION("Xilinx XilSEM driver"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/extcon/Kconfig +++ linux-xilinx-6.8.0/drivers/extcon/Kconfig @@ -116,7 +116,8 @@ config EXTCON_MAX8997 tristate "Maxim MAX8997 EXTCON Support" - depends on MFD_MAX8997 && IRQ_DOMAIN + depends on MFD_MAX8997 + select IRQ_DOMAIN help If you say yes here you get support for the MUIC device of Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory --- linux-xilinx-6.8.0.orig/drivers/firewire/nosy.c +++ linux-xilinx-6.8.0/drivers/firewire/nosy.c @@ -148,10 +148,12 @@ if (atomic_read(&buffer->size) == 0) return -ENODEV; - /* FIXME: Check length <= user_length. */ + length = buffer->head->length; + + if (length > user_length) + return 0; end = buffer->data + buffer->capacity; - length = buffer->head->length; if (&buffer->head->data[length] < end) { if (copy_to_user(data, buffer->head->data, length)) --- linux-xilinx-6.8.0.orig/drivers/firewire/ohci.c +++ linux-xilinx-6.8.0/drivers/firewire/ohci.c @@ -1556,6 +1556,8 @@ #define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff) #define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff) +static u32 get_cycle_time(struct fw_ohci *ohci); + static void handle_local_rom(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr) { @@ -1580,6 +1582,8 @@ (void *) ohci->config_rom + i, length); } + // Timestamping on behalf of the hardware. + response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci)); fw_core_handle_response(&ohci->card, &response); } @@ -1628,6 +1632,8 @@ fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); out: + // Timestamping on behalf of the hardware. + response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci)); fw_core_handle_response(&ohci->card, &response); } @@ -1670,8 +1676,6 @@ } } -static u32 get_cycle_time(struct fw_ohci *ohci); - static void at_context_transmit(struct context *ctx, struct fw_packet *packet) { unsigned long flags; @@ -2060,6 +2064,8 @@ ohci->generation = generation; reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) + reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); if (ohci->quirks & QUIRK_RESET_PACKET) ohci->request_generation = generation; @@ -2125,12 +2131,14 @@ return IRQ_NONE; /* - * busReset and postedWriteErr must not be cleared yet + * busReset and postedWriteErr events must not be cleared yet * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1) */ reg_write(ohci, OHCI1394_IntEventClear, event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); log_irqs(ohci, event); + if (event & OHCI1394_busReset) + reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset); if (event & OHCI1394_selfIDComplete) queue_work(selfid_workqueue, &ohci->bus_reset_work); --- linux-xilinx-6.8.0.orig/drivers/firmware/arm_ffa/driver.c +++ linux-xilinx-6.8.0/drivers/firmware/arm_ffa/driver.c @@ -790,7 +790,7 @@ part_id = packed_id_list[ids_processed++]; - if (!ids_count[list]) { /* Global Notification */ + if (ids_count[list] == 1) { /* Global Notification */ __do_sched_recv_cb(part_id, 0, false); continue; } --- linux-xilinx-6.8.0.orig/drivers/firmware/arm_scmi/raw_mode.c +++ linux-xilinx-6.8.0/drivers/firmware/arm_scmi/raw_mode.c @@ -921,7 +921,7 @@ rd->raw = raw; filp->private_data = rd; - return 0; + return nonseekable_open(inode, filp); } static int scmi_dbg_raw_mode_release(struct inode *inode, struct file *filp) @@ -950,6 +950,7 @@ .open = scmi_dbg_raw_mode_open, .release = scmi_dbg_raw_mode_release, .write = scmi_dbg_raw_mode_reset_write, + .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -959,6 +960,7 @@ .read = scmi_dbg_raw_mode_message_read, .write = scmi_dbg_raw_mode_message_write, .poll = scmi_dbg_raw_mode_message_poll, + .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -975,6 +977,7 @@ .read = scmi_dbg_raw_mode_message_read, .write = scmi_dbg_raw_mode_message_async_write, .poll = scmi_dbg_raw_mode_message_poll, + .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -998,6 +1001,7 @@ .release = scmi_dbg_raw_mode_release, .read = scmi_test_dbg_raw_mode_notif_read, .poll = scmi_test_dbg_raw_mode_notif_poll, + .llseek = no_llseek, .owner = THIS_MODULE, }; @@ -1021,6 +1025,7 @@ .release = scmi_dbg_raw_mode_release, .read = scmi_test_dbg_raw_mode_errors_read, .poll = scmi_test_dbg_raw_mode_errors_poll, + .llseek = no_llseek, .owner = THIS_MODULE, }; --- linux-xilinx-6.8.0.orig/drivers/firmware/arm_scmi/smc.c +++ linux-xilinx-6.8.0/drivers/firmware/arm_scmi/smc.c @@ -214,6 +214,13 @@ struct scmi_chan_info *cinfo = p; struct scmi_smc *scmi_info = cinfo->transport_info; + /* + * Different protocols might share the same chan info, so a previous + * smc_chan_free call might have already freed the structure. + */ + if (!scmi_info) + return 0; + /* Ignore any possible further reception on the IRQ path */ if (scmi_info->irq > 0) free_irq(scmi_info->irq, scmi_info); --- linux-xilinx-6.8.0.orig/drivers/firmware/cirrus/cs_dsp.c +++ linux-xilinx-6.8.0/drivers/firmware/cirrus/cs_dsp.c @@ -1053,9 +1053,16 @@ int len; }; -static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) +static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, unsigned int avail, + const u8 **str) { - int length; + int length, total_field_len; + + /* String fields are at least one __le32 */ + if (sizeof(__le32) > avail) { + *pos = NULL; + return 0; + } switch (bytes) { case 1: @@ -1068,10 +1075,16 @@ return 0; } + total_field_len = ((length + bytes) + 3) & ~0x03; + if ((unsigned int)total_field_len > avail) { + *pos = NULL; + return 0; + } + if (str) *str = *pos + bytes; - *pos += ((length + bytes) + 3) & ~0x03; + *pos += total_field_len; return length; } @@ -1096,71 +1109,134 @@ return val; } -static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data, - struct cs_dsp_coeff_parsed_alg *blk) +static int cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, + const struct wmfw_region *region, + struct cs_dsp_coeff_parsed_alg *blk) { const struct wmfw_adsp_alg_data *raw; + unsigned int data_len = le32_to_cpu(region->len); + unsigned int pos; + const u8 *tmp; + + raw = (const struct wmfw_adsp_alg_data *)region->data; switch (dsp->fw_ver) { case 0: case 1: - raw = (const struct wmfw_adsp_alg_data *)*data; - *data = raw->data; + if (sizeof(*raw) > data_len) + return -EOVERFLOW; blk->id = le32_to_cpu(raw->id); blk->name = raw->name; - blk->name_len = strlen(raw->name); + blk->name_len = strnlen(raw->name, ARRAY_SIZE(raw->name)); blk->ncoeff = le32_to_cpu(raw->ncoeff); + + pos = sizeof(*raw); break; default: - blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data); - blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data, + if (sizeof(raw->id) > data_len) + return -EOVERFLOW; + + tmp = region->data; + blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), &tmp); + pos = tmp - region->data; + + tmp = ®ion->data[pos]; + blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, data_len - pos, &blk->name); - cs_dsp_coeff_parse_string(sizeof(u16), data, NULL); - blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data); + if (!tmp) + return -EOVERFLOW; + + pos = tmp - region->data; + cs_dsp_coeff_parse_string(sizeof(u16), &tmp, data_len - pos, NULL); + if (!tmp) + return -EOVERFLOW; + + pos = tmp - region->data; + if (sizeof(raw->ncoeff) > (data_len - pos)) + return -EOVERFLOW; + + blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), &tmp); + pos += sizeof(raw->ncoeff); break; } + if ((int)blk->ncoeff < 0) + return -EOVERFLOW; + cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); + + return pos; } -static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data, - struct cs_dsp_coeff_parsed_coeff *blk) +static int cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, + const struct wmfw_region *region, + unsigned int pos, + struct cs_dsp_coeff_parsed_coeff *blk) { const struct wmfw_adsp_coeff_data *raw; + unsigned int data_len = le32_to_cpu(region->len); + unsigned int blk_len, blk_end_pos; const u8 *tmp; - int length; + + raw = (const struct wmfw_adsp_coeff_data *)®ion->data[pos]; + if (sizeof(raw->hdr) > (data_len - pos)) + return -EOVERFLOW; + + blk_len = le32_to_cpu(raw->hdr.size); + if (blk_len > S32_MAX) + return -EOVERFLOW; + + if (blk_len > (data_len - pos - sizeof(raw->hdr))) + return -EOVERFLOW; + + blk_end_pos = pos + sizeof(raw->hdr) + blk_len; + + blk->offset = le16_to_cpu(raw->hdr.offset); + blk->mem_type = le16_to_cpu(raw->hdr.type); switch (dsp->fw_ver) { case 0: case 1: - raw = (const struct wmfw_adsp_coeff_data *)*data; - *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); + if (sizeof(*raw) > (data_len - pos)) + return -EOVERFLOW; - blk->offset = le16_to_cpu(raw->hdr.offset); - blk->mem_type = le16_to_cpu(raw->hdr.type); blk->name = raw->name; - blk->name_len = strlen(raw->name); + blk->name_len = strnlen(raw->name, ARRAY_SIZE(raw->name)); blk->ctl_type = le16_to_cpu(raw->ctl_type); blk->flags = le16_to_cpu(raw->flags); blk->len = le32_to_cpu(raw->len); break; default: - tmp = *data; - blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); - blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp); - length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp); - blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, + pos += sizeof(raw->hdr); + tmp = ®ion->data[pos]; + blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, data_len - pos, &blk->name); - cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL); - cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL); + if (!tmp) + return -EOVERFLOW; + + pos = tmp - region->data; + cs_dsp_coeff_parse_string(sizeof(u8), &tmp, data_len - pos, NULL); + if (!tmp) + return -EOVERFLOW; + + pos = tmp - region->data; + cs_dsp_coeff_parse_string(sizeof(u16), &tmp, data_len - pos, NULL); + if (!tmp) + return -EOVERFLOW; + + pos = tmp - region->data; + if (sizeof(raw->ctl_type) + sizeof(raw->flags) + sizeof(raw->len) > + (data_len - pos)) + return -EOVERFLOW; + blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp); + pos += sizeof(raw->ctl_type); blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp); + pos += sizeof(raw->flags); blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp); - - *data = *data + sizeof(raw->hdr) + length; break; } @@ -1170,6 +1246,8 @@ cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); + + return blk_end_pos; } static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, @@ -1193,12 +1271,16 @@ struct cs_dsp_alg_region alg_region = {}; struct cs_dsp_coeff_parsed_alg alg_blk; struct cs_dsp_coeff_parsed_coeff coeff_blk; - const u8 *data = region->data; - int i, ret; + int i, pos, ret; + + pos = cs_dsp_coeff_parse_alg(dsp, region, &alg_blk); + if (pos < 0) + return pos; - cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk); for (i = 0; i < alg_blk.ncoeff; i++) { - cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk); + pos = cs_dsp_coeff_parse_coeff(dsp, region, pos, &coeff_blk); + if (pos < 0) + return pos; switch (coeff_blk.ctl_type) { case WMFW_CTL_TYPE_BYTES: @@ -1267,6 +1349,10 @@ const struct wmfw_adsp1_sizes *adsp1_sizes; adsp1_sizes = (void *)&firmware->data[pos]; + if (sizeof(*adsp1_sizes) > firmware->size - pos) { + cs_dsp_err(dsp, "%s: file truncated\n", file); + return 0; + } cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm), @@ -1283,6 +1369,10 @@ const struct wmfw_adsp2_sizes *adsp2_sizes; adsp2_sizes = (void *)&firmware->data[pos]; + if (sizeof(*adsp2_sizes) > firmware->size - pos) { + cs_dsp_err(dsp, "%s: file truncated\n", file); + return 0; + } cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym), @@ -1322,7 +1412,6 @@ struct regmap *regmap = dsp->regmap; unsigned int pos = 0; const struct wmfw_header *header; - const struct wmfw_adsp1_sizes *adsp1_sizes; const struct wmfw_footer *footer; const struct wmfw_region *region; const struct cs_dsp_region *mem; @@ -1338,10 +1427,8 @@ ret = -EINVAL; - pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); - if (pos >= firmware->size) { - cs_dsp_err(dsp, "%s: file too short, %zu bytes\n", - file, firmware->size); + if (sizeof(*header) >= firmware->size) { + ret = -EOVERFLOW; goto out_fw; } @@ -1369,22 +1456,36 @@ pos = sizeof(*header); pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); + if ((pos == 0) || (sizeof(*footer) > firmware->size - pos)) { + ret = -EOVERFLOW; + goto out_fw; + } footer = (void *)&firmware->data[pos]; pos += sizeof(*footer); if (le32_to_cpu(header->len) != pos) { - cs_dsp_err(dsp, "%s: unexpected header length %d\n", - file, le32_to_cpu(header->len)); + ret = -EOVERFLOW; goto out_fw; } cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file, le64_to_cpu(footer->timestamp)); - while (pos < firmware->size && - sizeof(*region) < firmware->size - pos) { + while (pos < firmware->size) { + /* Is there enough data for a complete block header? */ + if (sizeof(*region) > firmware->size - pos) { + ret = -EOVERFLOW; + goto out_fw; + } + region = (void *)&(firmware->data[pos]); + + if (le32_to_cpu(region->len) > firmware->size - pos - sizeof(*region)) { + ret = -EOVERFLOW; + goto out_fw; + } + region_name = "Unknown"; reg = 0; text = NULL; @@ -1441,16 +1542,6 @@ regions, le32_to_cpu(region->len), offset, region_name); - if (le32_to_cpu(region->len) > - firmware->size - pos - sizeof(*region)) { - cs_dsp_err(dsp, - "%s.%d: %s region len %d bytes exceeds file length %zu\n", - file, regions, region_name, - le32_to_cpu(region->len), firmware->size); - ret = -EINVAL; - goto out_fw; - } - if (text) { memcpy(text, region->data, le32_to_cpu(region->len)); cs_dsp_info(dsp, "%s: %s\n", file, text); @@ -1501,6 +1592,9 @@ cs_dsp_buf_free(&buf_list); kfree(text); + if (ret == -EOVERFLOW) + cs_dsp_err(dsp, "%s: file content overflows file data\n", file); + return ret; } @@ -2068,10 +2162,20 @@ pos = le32_to_cpu(hdr->len); blocks = 0; - while (pos < firmware->size && - sizeof(*blk) < firmware->size - pos) { + while (pos < firmware->size) { + /* Is there enough data for a complete block header? */ + if (sizeof(*blk) > firmware->size - pos) { + ret = -EOVERFLOW; + goto out_fw; + } + blk = (void *)(&firmware->data[pos]); + if (le32_to_cpu(blk->len) > firmware->size - pos - sizeof(*blk)) { + ret = -EOVERFLOW; + goto out_fw; + } + type = le16_to_cpu(blk->type); offset = le16_to_cpu(blk->offset); version = le32_to_cpu(blk->ver) >> 8; @@ -2168,17 +2272,6 @@ } if (reg) { - if (le32_to_cpu(blk->len) > - firmware->size - pos - sizeof(*blk)) { - cs_dsp_err(dsp, - "%s.%d: %s region len %d bytes exceeds file length %zu\n", - file, blocks, region_name, - le32_to_cpu(blk->len), - firmware->size); - ret = -EINVAL; - goto out_fw; - } - buf = cs_dsp_buf_alloc(blk->data, le32_to_cpu(blk->len), &buf_list); @@ -2218,6 +2311,10 @@ regmap_async_complete(regmap); cs_dsp_buf_free(&buf_list); kfree(text); + + if (ret == -EOVERFLOW) + cs_dsp_err(dsp, "%s: file content overflows file data\n", file); + return ret; } --- linux-xilinx-6.8.0.orig/drivers/firmware/dmi-id.c +++ linux-xilinx-6.8.0/drivers/firmware/dmi-id.c @@ -169,9 +169,14 @@ return 0; } +static void dmi_dev_release(struct device *dev) +{ + kfree(dev); +} + static struct class dmi_class = { .name = "dmi", - .dev_release = (void(*)(struct device *)) kfree, + .dev_release = dmi_dev_release, .dev_uevent = dmi_dev_uevent, }; --- linux-xilinx-6.8.0.orig/drivers/firmware/dmi_scan.c +++ linux-xilinx-6.8.0/drivers/firmware/dmi_scan.c @@ -102,6 +102,17 @@ const struct dmi_header *dm = (const struct dmi_header *)data; /* + * If a short entry is found (less than 4 bytes), not only it + * is invalid, but we cannot reliably locate the next entry. + */ + if (dm->length < sizeof(struct dmi_header)) { + pr_warn(FW_BUG + "Corrupted DMI table, offset %zd (only %d entries processed)\n", + data - buf, i); + break; + } + + /* * We want to know the total length (formatted area and * strings) before decoding to make sure we won't run off the * table in dmi_decode or dmi_string --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/Makefile +++ linux-xilinx-6.8.0/drivers/firmware/efi/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o obj-$(CONFIG_EFI_TEST) += test/ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o +obj-$(CONFIG_EFI) += secureboot.o obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/efi-init.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/efi-init.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -237,6 +238,13 @@ return; } + efi_set_secure_boot(efi_get__secure_boot()); + +#ifdef CONFIG_LOCK_DOWN_IN_SECURE_BOOT + if (efi_enabled(EFI_SECURE_BOOT)) + security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX); +#endif + reserve_regions(); /* * For memblock manipulation, the cap should come after the memblock_add(). --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/efi.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/efi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -203,6 +204,8 @@ name_size = sizeof(name); + if (!efi.get_next_variable) + return false; status = efi.get_next_variable(&name_size, &name, &guid); if (status == EFI_UNSUPPORTED) return false; @@ -597,7 +600,8 @@ {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, &efi_mem_attr_table, "MEMATTR" }, {LINUX_EFI_RANDOM_SEED_TABLE_GUID, &efi_rng_seed, "RNG" }, {LINUX_EFI_TPM_EVENT_LOG_GUID, &efi.tpm_log, "TPMEventLog" }, - {LINUX_EFI_TPM_FINAL_LOG_GUID, &efi.tpm_final_log, "TPMFinalLog" }, + {EFI_TCG2_FINAL_EVENTS_TABLE_GUID, &efi.tpm_final_log, "TPMFinalLog" }, + {EFI_CC_FINAL_EVENTS_TABLE_GUID, &efi.tpm_final_log, "CCFinalLog" }, {LINUX_EFI_MEMRESERVE_TABLE_GUID, &mem_reserve, "MEMRESERVE" }, {LINUX_EFI_INITRD_MEDIA_GUID, &initrd, "INITRD" }, {EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" }, @@ -990,40 +994,101 @@ return -EINVAL; } +struct efi_error_code { + efi_status_t status; + int errno; + const char *description; +}; + +static const struct efi_error_code efi_error_codes[] = { + { EFI_SUCCESS, 0, "Success"}, +#if 0 + { EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"}, +#endif + { EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"}, + { EFI_UNSUPPORTED, -ENOSYS, "Unsupported"}, + { EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"}, + { EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"}, + { EFI_NOT_READY, -EAGAIN, "Not Ready"}, + { EFI_DEVICE_ERROR, -EIO, "Device Error"}, + { EFI_WRITE_PROTECTED, -EROFS, "Write Protected"}, + { EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"}, +#if 0 + { EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"}, + { EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"}, + { EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"}, + { EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"}, +#endif + { EFI_NOT_FOUND, -ENOENT, "Not Found"}, +#if 0 + { EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"}, + { EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"}, + { EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"}, + { EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"}, + { EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"}, + { EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"}, +#endif + { EFI_ABORTED, -EINTR, "Aborted"}, +#if 0 + { EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"}, + { EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"}, + { EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"}, + { EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"}, +#endif + { EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"}, +#if 0 + { EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"}, + { EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"}, + { EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"}, + { EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"}, + { EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"}, + + // warnings + { EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"}, + { EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"}, + { EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"}, + { EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"}, +#endif +}; + +static int +efi_status_cmp_bsearch(const void *key, const void *item) +{ + u64 status = (u64)(uintptr_t)key; + struct efi_error_code *code = (struct efi_error_code *)item; + + if (status < code->status) + return -1; + if (status > code->status) + return 1; + return 0; +} + int efi_status_to_err(efi_status_t status) { - int err; + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); - switch (status) { - case EFI_SUCCESS: - err = 0; - break; - case EFI_INVALID_PARAMETER: - err = -EINVAL; - break; - case EFI_OUT_OF_RESOURCES: - err = -ENOSPC; - break; - case EFI_DEVICE_ERROR: - err = -EIO; - break; - case EFI_WRITE_PROTECTED: - err = -EROFS; - break; - case EFI_SECURITY_VIOLATION: - err = -EACCES; - break; - case EFI_NOT_FOUND: - err = -ENOENT; - break; - case EFI_ABORTED: - err = -EINTR; - break; - default: - err = -EINVAL; - } + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, + efi_status_cmp_bsearch); + if (!found) + return -EINVAL; + return found->errno; +} + +const char * +efi_status_to_str(efi_status_t status) +{ + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); - return err; + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, + efi_status_cmp_bsearch); + if (!found) + return "Unknown error code"; + return found->description; } EXPORT_SYMBOL_GPL(efi_status_to_err); --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/fdtparams.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/fdtparams.c @@ -16,16 +16,24 @@ MMSIZE, DCSIZE, DCVERS, + SCBOOT, PARAMCOUNT }; +static u32 __secure_boot __initdata = efi_secureboot_mode_unset; +u32 __init efi_get__secure_boot(void) +{ + return __secure_boot; +} + static __initconst const char name[][22] = { [SYSTAB] = "System Table ", [MMBASE] = "MemMap Address ", [MMSIZE] = "MemMap Size ", [DCSIZE] = "MemMap Desc. Size ", [DCVERS] = "MemMap Desc. Version ", + [SCBOOT] = "Secure Boot Enabled ", }; static __initconst const struct { @@ -53,6 +61,7 @@ [MMSIZE] = "linux,uefi-mmap-size", [DCSIZE] = "linux,uefi-mmap-desc-size", [DCVERS] = "linux,uefi-mmap-desc-ver", + [SCBOOT] = "linux,uefi-secure-boot", } } }; @@ -95,6 +104,7 @@ [MMSIZE] = { &mm->size, sizeof(mm->size) }, [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, + [SCBOOT] = { &__secure_boot, sizeof(__secure_boot) }, }; BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/efi-stub-helper.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -24,6 +25,8 @@ static bool efi_nosoftreserve; static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA); +int efi_mem_encrypt; + bool __pure __efi_soft_reserve_enabled(void) { return !efi_nosoftreserve; @@ -75,6 +78,12 @@ efi_noinitrd = true; } else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) { efi_no5lvl = true; + } else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) && + !strcmp(param, "mem_encrypt") && val) { + if (parse_option_str(val, "on")) + efi_mem_encrypt = 1; + else if (parse_option_str(val, "off")) + efi_mem_encrypt = -1; } else if (!strcmp(param, "efi") && val) { efi_nochunk = parse_option_str(val, "nochunk"); efi_novamap |= parse_option_str(val, "novamap"); @@ -193,7 +202,7 @@ *load_options_size = load_option_unpacked.optional_data_size; } -enum efistub_event { +enum efistub_event_type { EFISTUB_EVT_INITRD, EFISTUB_EVT_LOAD_OPTIONS, EFISTUB_EVT_COUNT, @@ -219,54 +228,95 @@ }, }; +static_assert(sizeof(efi_tcg2_event_t) == sizeof(efi_cc_event_t)); + +union efistub_event { + efi_tcg2_event_t tcg2_data; + efi_cc_event_t cc_data; +}; + +struct efistub_measured_event { + union efistub_event event_data; + TCG_PCClientTaggedEvent tagged_event __packed; +}; + static efi_status_t efi_measure_tagged_event(unsigned long load_addr, unsigned long load_size, - enum efistub_event event) + enum efistub_event_type event) { + union { + efi_status_t + (__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t, + u64, const union efistub_event *); + struct { u32 hash_log_extend_event; } mixed_mode; + } method; + struct efistub_measured_event *evt; + int size = struct_size(evt, tagged_event.tagged_event_data, + events[event].event_data_len); efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; efi_tcg2_protocol_t *tcg2 = NULL; + union efistub_event ev; efi_status_t status; + void *protocol; efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2); if (tcg2) { - struct efi_measured_event { - efi_tcg2_event_t event_data; - efi_tcg2_tagged_event_t tagged_event; - u8 tagged_event_data[]; - } *evt; - int size = sizeof(*evt) + events[event].event_data_len; - - status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, - (void **)&evt); - if (status != EFI_SUCCESS) - goto fail; - - evt->event_data = (struct efi_tcg2_event){ + ev.tcg2_data = (struct efi_tcg2_event){ .event_size = size, - .event_header.header_size = sizeof(evt->event_data.event_header), + .event_header.header_size = sizeof(ev.tcg2_data.event_header), .event_header.header_version = EFI_TCG2_EVENT_HEADER_VERSION, .event_header.pcr_index = events[event].pcr_index, .event_header.event_type = EV_EVENT_TAG, }; + protocol = tcg2; + method.hash_log_extend_event = + (void *)efi_table_attr(tcg2, hash_log_extend_event); + } else { + efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID; + efi_cc_protocol_t *cc = NULL; + + efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc); + if (!cc) + return EFI_UNSUPPORTED; - evt->tagged_event = (struct efi_tcg2_tagged_event){ - .tagged_event_id = events[event].event_id, - .tagged_event_data_size = events[event].event_data_len, + ev.cc_data = (struct efi_cc_event){ + .event_size = size, + .event_header.header_size = sizeof(ev.cc_data.event_header), + .event_header.header_version = EFI_CC_EVENT_HEADER_VERSION, + .event_header.event_type = EV_EVENT_TAG, }; - memcpy(evt->tagged_event_data, events[event].event_data, - events[event].event_data_len); - - status = efi_call_proto(tcg2, hash_log_extend_event, 0, - load_addr, load_size, &evt->event_data); - efi_bs_call(free_pool, evt); - + status = efi_call_proto(cc, map_pcr_to_mr_index, + events[event].pcr_index, + &ev.cc_data.event_header.mr_index); if (status != EFI_SUCCESS) goto fail; - return EFI_SUCCESS; + + protocol = cc; + method.hash_log_extend_event = + (void *)efi_table_attr(cc, hash_log_extend_event); } - return EFI_UNSUPPORTED; + status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, (void **)&evt); + if (status != EFI_SUCCESS) + goto fail; + + *evt = (struct efistub_measured_event) { + .event_data = ev, + .tagged_event.tagged_event_id = events[event].event_id, + .tagged_event.tagged_event_data_size = events[event].event_data_len, + }; + + memcpy(evt->tagged_event.tagged_event_data, events[event].event_data, + events[event].event_data_len); + + status = efi_fn_call(&method, hash_log_extend_event, protocol, 0, + load_addr, load_size, &evt->event_data); + efi_bs_call(free_pool, evt); + + if (status == EFI_SUCCESS) + return EFI_SUCCESS; + fail: efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status); return status; --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/efi-stub.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/efi-stub.c @@ -167,7 +167,7 @@ si = setup_graphics(); - efi_retrieve_tpm2_eventlog(); + efi_retrieve_eventlog(); /* Ask the firmware to clear memory on unclean shutdown */ efi_enable_reset_attack_mitigation(); --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/efistub.h +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/efistub.h @@ -37,8 +37,8 @@ extern bool efi_nochunk; extern bool efi_nokaslr; extern int efi_loglevel; +extern int efi_mem_encrypt; extern bool efi_novamap; - extern const efi_system_table_t *efi_system_table; typedef union efi_dxe_services_table efi_dxe_services_table_t; @@ -171,7 +171,7 @@ * the EFI memory map. Other related structures, e.g. x86 e820ext, need * to factor in this headroom requirement as well. */ -#define EFI_MMAP_NR_SLACK_SLOTS 8 +#define EFI_MMAP_NR_SLACK_SLOTS 16 typedef struct efi_generic_dev_path efi_device_path_protocol_t; @@ -843,14 +843,14 @@ /* u8[] event follows here */ } __packed; -struct efi_tcg2_tagged_event { - u32 tagged_event_id; - u32 tagged_event_data_size; - /* u8 tagged event data follows here */ -} __packed; +/* from TCG PC Client Platform Firmware Profile Specification */ +typedef struct tdTCG_PCClientTaggedEvent { + u32 tagged_event_id; + u32 tagged_event_data_size; + u8 tagged_event_data[]; +} TCG_PCClientTaggedEvent; typedef struct efi_tcg2_event efi_tcg2_event_t; -typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t; typedef union efi_tcg2_protocol efi_tcg2_protocol_t; union efi_tcg2_protocol { @@ -882,6 +882,87 @@ } mixed_mode; }; +typedef struct { + u8 major; + u8 minor; +} efi_cc_version_t; + +typedef struct { + u8 type; + u8 sub_type; +} efi_cc_type_t; + +/* EFI CC type/subtype defines */ +#define EFI_CC_TYPE_NONE 0 +#define EFI_CC_TYPE_AMD_SEV 1 +#define EFI_CC_TYPE_INTEL_TDX 2 + +typedef u32 efi_cc_mr_index_t; + +struct efi_cc_event { + u32 event_size; + struct { + u32 header_size; + u16 header_version; + u32 mr_index; + u32 event_type; + } __packed event_header; + /* u8[] event follows here */ +} __packed; + +typedef struct efi_cc_event efi_cc_event_t; + +typedef u32 efi_cc_event_log_bitmap_t; +typedef u32 efi_cc_event_log_format_t; +typedef u32 efi_cc_event_algorithm_bitmap_t; + +typedef struct { + u8 size; + efi_cc_version_t structure_version; + efi_cc_version_t protocol_version; + efi_cc_event_algorithm_bitmap_t hash_algorithm_bitmap; + efi_cc_event_log_bitmap_t supported_event_logs; + efi_cc_type_t cc_type; +} efi_cc_boot_service_cap_t; + +#define EFI_CC_EVENT_HEADER_VERSION 1 + +#define EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004 + +#define EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002 + +typedef union efi_cc_protocol efi_cc_protocol_t; + +union efi_cc_protocol { + struct { + efi_status_t + (__efiapi *get_capability)(efi_cc_protocol_t *, + efi_cc_boot_service_cap_t *); + + efi_status_t + (__efiapi *get_event_log)(efi_cc_protocol_t *, + efi_cc_event_log_format_t, + efi_physical_addr_t *, + efi_physical_addr_t *, + efi_bool_t *); + + efi_status_t + (__efiapi *hash_log_extend_event)(efi_cc_protocol_t *, u64, + efi_physical_addr_t, u64, + const efi_cc_event_t *); + + efi_status_t + (__efiapi *map_pcr_to_mr_index)(efi_cc_protocol_t *, u32, + efi_cc_mr_index_t *); + }; + struct { + u32 get_capability; + u32 get_event_log; + u32 hash_log_extend_event; + u32 map_pcr_to_mr_index; + } mixed_mode; +}; + struct riscv_efi_boot_protocol { u64 revision; @@ -1061,7 +1142,7 @@ efi_enable_reset_attack_mitigation(void) { } #endif -void efi_retrieve_tpm2_eventlog(void); +void efi_retrieve_eventlog(void); struct screen_info *alloc_screen_info(void); struct screen_info *__alloc_screen_info(void); --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/fdt.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/fdt.c @@ -132,6 +132,12 @@ } } + fdt_val32 = cpu_to_fdt32(efi_get_secureboot()); + status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", + &fdt_val32, sizeof(fdt_val32)); + if (status) + goto fdt_set_fail; + /* Shrink the FDT back to its minimum size: */ fdt_pack(fdt); @@ -335,8 +341,8 @@ fail: efi_free(fdt_size, fdt_addr); - - efi_bs_call(free_pool, priv.runtime_map); + if (!efi_novamap) + efi_bs_call(free_pool, priv.runtime_map); return EFI_LOAD_ERROR; } --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/loongarch.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/loongarch.c @@ -41,7 +41,7 @@ unsigned long __weak kernel_entry_address(unsigned long kernel_addr, efi_loaded_image_t *image) { - return *(unsigned long *)(kernel_addr + 8) - VMLINUX_LOAD_ADDRESS + kernel_addr; + return *(unsigned long *)(kernel_addr + 8) - PHYSADDR(VMLINUX_LOAD_ADDRESS) + kernel_addr; } efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/randomalloc.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/randomalloc.c @@ -120,7 +120,7 @@ continue; } - target = round_up(md->phys_addr, align) + target_slot * align; + target = round_up(max_t(u64, md->phys_addr, alloc_min), align) + target_slot * align; pages = size / EFI_PAGE_SIZE; status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/tpm.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/tpm.c @@ -47,39 +47,18 @@ #endif -void efi_retrieve_tpm2_eventlog(void) +static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_location, + efi_physical_addr_t log_last_entry, + efi_bool_t truncated, + struct efi_tcg2_final_events_table *final_events_table) { - efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID; efi_status_t status; - efi_physical_addr_t log_location = 0, log_last_entry = 0; struct linux_efi_tpm_eventlog *log_tbl = NULL; - struct efi_tcg2_final_events_table *final_events_table = NULL; unsigned long first_entry_addr, last_entry_addr; size_t log_size, last_entry_size; - efi_bool_t truncated; - int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; - efi_tcg2_protocol_t *tcg2_protocol = NULL; int final_events_size = 0; - status = efi_bs_call(locate_protocol, &tcg2_guid, NULL, - (void **)&tcg2_protocol); - if (status != EFI_SUCCESS) - return; - - status = efi_call_proto(tcg2_protocol, get_event_log, version, - &log_location, &log_last_entry, &truncated); - - if (status != EFI_SUCCESS || !log_location) { - version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; - status = efi_call_proto(tcg2_protocol, get_event_log, version, - &log_location, &log_last_entry, - &truncated); - if (status != EFI_SUCCESS || !log_location) - return; - - } - first_entry_addr = (unsigned long) log_location; /* @@ -93,8 +72,10 @@ * get_event_log only returns the address of the last entry. * We need to calculate its size to deduce the full size of * the logs. + * + * CC Event log also uses TCG2 format, handle it same as TPM2. */ - if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { + if (version > EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) { /* * The TCG2 log format has variable length entries, * and the information to decode the hash algorithms @@ -127,8 +108,6 @@ * Figure out whether any events have already been logged to the * final events structure, and if so how much space they take up */ - if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) - final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID); if (final_events_table && final_events_table->nr_events) { struct tcg_pcr_event2_head *header; int offset; @@ -165,3 +144,50 @@ err_free: efi_bs_call(free_pool, log_tbl); } + +void efi_retrieve_eventlog(void) +{ + struct efi_tcg2_final_events_table *final_events_table = NULL; + efi_physical_addr_t log_location = 0, log_last_entry = 0; + efi_guid_t tpm2_guid = EFI_TCG2_PROTOCOL_GUID; + int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; + efi_tcg2_protocol_t *tpm2 = NULL; + efi_bool_t truncated; + efi_status_t status; + + status = efi_bs_call(locate_protocol, &tpm2_guid, NULL, (void **)&tpm2); + if (status == EFI_SUCCESS) { + status = efi_call_proto(tpm2, get_event_log, version, &log_location, + &log_last_entry, &truncated); + + if (status != EFI_SUCCESS || !log_location) { + version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; + status = efi_call_proto(tpm2, get_event_log, version, + &log_location, &log_last_entry, + &truncated); + } else { + final_events_table = + get_efi_config_table(EFI_TCG2_FINAL_EVENTS_TABLE_GUID); + } + } else { + efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID; + efi_cc_protocol_t *cc = NULL; + + status = efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc); + if (status != EFI_SUCCESS) + return; + + version = EFI_CC_EVENT_LOG_FORMAT_TCG_2; + status = efi_call_proto(cc, get_event_log, version, &log_location, + &log_last_entry, &truncated); + + final_events_table = + get_efi_config_table(EFI_CC_FINAL_EVENTS_TABLE_GUID); + } + + if (status != EFI_SUCCESS || !log_location) + return; + + efi_retrieve_tcg2_eventlog(version, log_location, log_last_entry, + truncated, final_events_table); +} --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/x86-stub.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/x86-stub.c @@ -21,6 +21,8 @@ #include "efistub.h" #include "x86-stub.h" +extern char _bss[], _ebss[]; + const efi_system_table_t *efi_system_table; const efi_dxe_services_table_t *efi_dxe_table; static efi_loaded_image_t *image = NULL; @@ -236,6 +238,15 @@ rounded_end = roundup(start + size, EFI_PAGE_SIZE); if (memattr != NULL) { + status = efi_call_proto(memattr, set_memory_attributes, + rounded_start, + rounded_end - rounded_start, + EFI_MEMORY_RO); + if (status != EFI_SUCCESS) { + efi_warn("Failed to set EFI_MEMORY_RO attribute\n"); + return status; + } + status = efi_call_proto(memattr, clear_memory_attributes, rounded_start, rounded_end - rounded_start, @@ -465,6 +476,9 @@ efi_status_t status; char *cmdline_ptr; + if (efi_is_native()) + memset(_bss, 0, _ebss - _bss); + efi_system_table = sys_table_arg; /* Check if we were booted by the EFI firmware */ @@ -482,6 +496,7 @@ hdr->vid_mode = 0xffff; hdr->type_of_loader = 0x21; + hdr->initrd_addr_max = INT_MAX; /* Convert unicode cmdline to ascii */ cmdline_ptr = efi_convert_cmdline(image, &options_size); @@ -761,6 +776,26 @@ efi_warn("Decompression failed: %s\n", str); } +static const char *cmdline_memmap_override; + +static efi_status_t parse_options(const char *cmdline) +{ + static const char opts[][14] = { + "mem=", "memmap=", "efi_fake_mem=", "hugepages=" + }; + + for (int i = 0; i < ARRAY_SIZE(opts); i++) { + const char *p = strstr(cmdline, opts[i]); + + if (p == cmdline || (p > cmdline && isspace(p[-1]))) { + cmdline_memmap_override = opts[i]; + break; + } + } + + return efi_parse_options(cmdline); +} + static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry) { unsigned long virt_addr = LOAD_PHYSICAL_ADDR; @@ -792,6 +827,10 @@ !memcmp(efistub_fw_vendor(), ami, sizeof(ami))) { efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n"); seed[0] = 0; + } else if (cmdline_memmap_override) { + efi_info("%s detected on the kernel command line - disabling physical KASLR\n", + cmdline_memmap_override); + seed[0] = 0; } boot_params_ptr->hdr.loadflags |= KASLR_FLAG; @@ -812,7 +851,7 @@ *kernel_entry = addr + entry; - return efi_adjust_memory_range_protection(addr, kernel_total_size); + return efi_adjust_memory_range_protection(addr, kernel_text_size); } static void __noreturn enter_kernel(unsigned long kernel_addr, @@ -868,7 +907,7 @@ } #ifdef CONFIG_CMDLINE_BOOL - status = efi_parse_options(CONFIG_CMDLINE); + status = parse_options(CONFIG_CMDLINE); if (status != EFI_SUCCESS) { efi_err("Failed to parse options\n"); goto fail; @@ -877,13 +916,16 @@ if (!IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) { unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr | ((u64)boot_params->ext_cmd_line_ptr << 32)); - status = efi_parse_options((char *)cmdline_paddr); + status = parse_options((char *)cmdline_paddr); if (status != EFI_SUCCESS) { efi_err("Failed to parse options\n"); goto fail; } } + if (efi_mem_encrypt > 0) + hdr->xloadflags |= XLF_MEM_ENCRYPTION; + status = efi_decompress_kernel(&kernel_entry); if (status != EFI_SUCCESS) { efi_err("Failed to decompress kernel\n"); @@ -923,7 +965,7 @@ efi_random_get_seed(); - efi_retrieve_tpm2_eventlog(); + efi_retrieve_eventlog(); setup_graphics(boot_params); @@ -958,8 +1000,6 @@ void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, struct boot_params *boot_params) { - extern char _bss[], _ebss[]; - memset(_bss, 0, _ebss - _bss); efi_stub_entry(handle, sys_table_arg, boot_params); } --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/libstub/zboot.lds +++ linux-xilinx-6.8.0/drivers/firmware/efi/libstub/zboot.lds @@ -41,6 +41,7 @@ } /DISCARD/ : { + *(.discard .discard.*) *(.modinfo .init.modinfo) } } --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/memmap.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/memmap.c @@ -15,10 +15,6 @@ #include #include -#ifndef __efi_memmap_free -#define __efi_memmap_free(phys, size, flags) do { } while (0) -#endif - /** * __efi_memmap_init - Common code for mapping the EFI memory map * @data: EFI memory map data @@ -51,11 +47,6 @@ return -ENOMEM; } - if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB)) - __efi_memmap_free(efi.memmap.phys_map, - efi.memmap.desc_size * efi.memmap.nr_map, - efi.memmap.flags); - map.phys_map = data->phys_map; map.nr_map = data->size / data->desc_size; map.map_end = map.map + data->size; --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/secureboot.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/secureboot.c @@ -0,0 +1,38 @@ +/* Core kernel secure boot support. + * + * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include + +/* + * Decide what to do when UEFI secure boot mode is enabled. + */ +void __init efi_set_secure_boot(enum efi_secureboot_mode mode) +{ + if (efi_enabled(EFI_BOOT)) { + switch (mode) { + case efi_secureboot_mode_disabled: + pr_info("Secure boot disabled\n"); + break; + case efi_secureboot_mode_enabled: + set_bit(EFI_SECURE_BOOT, &efi.flags); + pr_info("Secure boot enabled\n"); + break; + default: + pr_warn("Secure boot could not be determined (mode %u)\n", + mode); + break; + } + } +} --- linux-xilinx-6.8.0.orig/drivers/firmware/efi/unaccepted_memory.c +++ linux-xilinx-6.8.0/drivers/firmware/efi/unaccepted_memory.c @@ -4,6 +4,7 @@ #include #include #include +#include #include /* Protects unaccepted memory bitmap and accepting_list */ @@ -149,6 +150,9 @@ } list_del(&range.list); + + touch_softlockup_watchdog(); + spin_unlock_irqrestore(&unaccepted_memory_lock, flags); } --- linux-xilinx-6.8.0.orig/drivers/firmware/microchip/mpfs-auto-update.c +++ linux-xilinx-6.8.0/drivers/firmware/microchip/mpfs-auto-update.c @@ -206,10 +206,12 @@ if (ret | response->resp_status) { dev_warn(priv->dev, "Verification of Upgrade Image failed!\n"); ret = ret ? ret : -EBADMSG; + goto free_message; } dev_info(priv->dev, "Verification of Upgrade Image passed!\n"); +free_message: devm_kfree(priv->dev, message); free_response: devm_kfree(priv->dev, response); --- linux-xilinx-6.8.0.orig/drivers/firmware/psci/psci.c +++ linux-xilinx-6.8.0/drivers/firmware/psci/psci.c @@ -497,10 +497,12 @@ static int psci_system_suspend(unsigned long unused) { + int err; phys_addr_t pa_cpu_resume = __pa_symbol(cpu_resume); - return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), + err = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), pa_cpu_resume, 0, 0); + return psci_to_linux_errno(err); } static int psci_system_suspend_enter(suspend_state_t state) --- linux-xilinx-6.8.0.orig/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c +++ linux-xilinx-6.8.0/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c @@ -221,6 +221,19 @@ * alignment of 8 bytes (64 bits) for GUIDs. Our definition of efi_guid_t, * however, has an alignment of 4 byte (32 bits). So far, this seems to work * fine here. See also the comment on the typedef of efi_guid_t. + * + * Note: It looks like uefisecapp is quite picky about how the memory passed to + * it is structured and aligned. In particular the request/response setup used + * for QSEE_CMD_UEFI_GET_VARIABLE. While qcom_qseecom_app_send(), in theory, + * accepts separate buffers/addresses for the request and response parts, in + * practice, however, it seems to expect them to be both part of a larger + * contiguous block. We initially allocated separate buffers for the request + * and response but this caused the QSEE_CMD_UEFI_GET_VARIABLE command to + * either not write any response to the response buffer or outright crash the + * device. Therefore, we now allocate a single contiguous block of DMA memory + * for both and properly align the data using the macros below. In particular, + * request and response structs are aligned at 8 byte (via __reqdata_offs()), + * following the driver that this has been reverse-engineered from. */ #define qcuefi_buf_align_fields(fields...) \ ({ \ @@ -244,6 +257,12 @@ #define __array_offs(type, count, offset) \ __field_impl(sizeof(type) * (count), __alignof__(type), offset) +#define __array_offs_aligned(type, count, align, offset) \ + __field_impl(sizeof(type) * (count), align, offset) + +#define __reqdata_offs(size, offset) \ + __array_offs_aligned(u8, size, 8, offset) + #define __array(type, count) __array_offs(type, count, NULL) #define __field_offs(type, offset) __array_offs(type, 1, offset) #define __field(type) __array_offs(type, 1, NULL) @@ -277,10 +296,15 @@ unsigned long buffer_size = *data_size; efi_status_t efi_status = EFI_SUCCESS; unsigned long name_length; + dma_addr_t cmd_buf_dma; + size_t cmd_buf_size; + void *cmd_buf; size_t guid_offs; size_t name_offs; size_t req_size; size_t rsp_size; + size_t req_offs; + size_t rsp_offs; ssize_t status; if (!name || !guid) @@ -304,17 +328,19 @@ __array(u8, buffer_size) ); - req_data = kzalloc(req_size, GFP_KERNEL); - if (!req_data) { + cmd_buf_size = qcuefi_buf_align_fields( + __reqdata_offs(req_size, &req_offs) + __reqdata_offs(rsp_size, &rsp_offs) + ); + + cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL); + if (!cmd_buf) { efi_status = EFI_OUT_OF_RESOURCES; goto out; } - rsp_data = kzalloc(rsp_size, GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + req_data = cmd_buf + req_offs; + rsp_data = cmd_buf + rsp_offs; req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE; req_data->data_size = buffer_size; @@ -332,7 +358,9 @@ memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size); - status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size); + status = qcom_qseecom_app_send(qcuefi->client, + cmd_buf_dma + req_offs, req_size, + cmd_buf_dma + rsp_offs, rsp_size); if (status) { efi_status = EFI_DEVICE_ERROR; goto out_free; @@ -407,9 +435,7 @@ memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size); out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); + qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma); out: return efi_status; } @@ -422,10 +448,15 @@ struct qsee_rsp_uefi_set_variable *rsp_data; efi_status_t efi_status = EFI_SUCCESS; unsigned long name_length; + dma_addr_t cmd_buf_dma; + size_t cmd_buf_size; + void *cmd_buf; size_t name_offs; size_t guid_offs; size_t data_offs; size_t req_size; + size_t req_offs; + size_t rsp_offs; ssize_t status; if (!name || !guid) @@ -450,17 +481,19 @@ __array_offs(u8, data_size, &data_offs) ); - req_data = kzalloc(req_size, GFP_KERNEL); - if (!req_data) { + cmd_buf_size = qcuefi_buf_align_fields( + __reqdata_offs(req_size, &req_offs) + __reqdata_offs(sizeof(*rsp_data), &rsp_offs) + ); + + cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL); + if (!cmd_buf) { efi_status = EFI_OUT_OF_RESOURCES; goto out; } - rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + req_data = cmd_buf + req_offs; + rsp_data = cmd_buf + rsp_offs; req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE; req_data->attributes = attributes; @@ -483,8 +516,9 @@ if (data_size) memcpy(((void *)req_data) + req_data->data_offset, data, req_data->data_size); - status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, - sizeof(*rsp_data)); + status = qcom_qseecom_app_send(qcuefi->client, + cmd_buf_dma + req_offs, req_size, + cmd_buf_dma + rsp_offs, sizeof(*rsp_data)); if (status) { efi_status = EFI_DEVICE_ERROR; goto out_free; @@ -507,9 +541,7 @@ } out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); + qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma); out: return efi_status; } @@ -521,10 +553,15 @@ struct qsee_req_uefi_get_next_variable *req_data; struct qsee_rsp_uefi_get_next_variable *rsp_data; efi_status_t efi_status = EFI_SUCCESS; + dma_addr_t cmd_buf_dma; + size_t cmd_buf_size; + void *cmd_buf; size_t guid_offs; size_t name_offs; size_t req_size; size_t rsp_size; + size_t req_offs; + size_t rsp_offs; ssize_t status; if (!name_size || !name || !guid) @@ -545,17 +582,19 @@ __array(*name, *name_size / sizeof(*name)) ); - req_data = kzalloc(req_size, GFP_KERNEL); - if (!req_data) { + cmd_buf_size = qcuefi_buf_align_fields( + __reqdata_offs(req_size, &req_offs) + __reqdata_offs(rsp_size, &rsp_offs) + ); + + cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL); + if (!cmd_buf) { efi_status = EFI_OUT_OF_RESOURCES; goto out; } - rsp_data = kzalloc(rsp_size, GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + req_data = cmd_buf + req_offs; + rsp_data = cmd_buf + rsp_offs; req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE; req_data->guid_offset = guid_offs; @@ -572,7 +611,9 @@ goto out_free; } - status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size); + status = qcom_qseecom_app_send(qcuefi->client, + cmd_buf_dma + req_offs, req_size, + cmd_buf_dma + rsp_offs, rsp_size); if (status) { efi_status = EFI_DEVICE_ERROR; goto out_free; @@ -645,9 +686,7 @@ } out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); + qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma); out: return efi_status; } @@ -659,26 +698,34 @@ struct qsee_req_uefi_query_variable_info *req_data; struct qsee_rsp_uefi_query_variable_info *rsp_data; efi_status_t efi_status = EFI_SUCCESS; + dma_addr_t cmd_buf_dma; + size_t cmd_buf_size; + void *cmd_buf; + size_t req_offs; + size_t rsp_offs; int status; - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); - if (!req_data) { + cmd_buf_size = qcuefi_buf_align_fields( + __reqdata_offs(sizeof(*req_data), &req_offs) + __reqdata_offs(sizeof(*rsp_data), &rsp_offs) + ); + + cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL); + if (!cmd_buf) { efi_status = EFI_OUT_OF_RESOURCES; goto out; } - rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); - if (!rsp_data) { - efi_status = EFI_OUT_OF_RESOURCES; - goto out_free_req; - } + req_data = cmd_buf + req_offs; + rsp_data = cmd_buf + rsp_offs; req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO; req_data->attributes = attr; req_data->length = sizeof(*req_data); - status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data, - sizeof(*rsp_data)); + status = qcom_qseecom_app_send(qcuefi->client, + cmd_buf_dma + req_offs, sizeof(*req_data), + cmd_buf_dma + rsp_offs, sizeof(*rsp_data)); if (status) { efi_status = EFI_DEVICE_ERROR; goto out_free; @@ -711,9 +758,7 @@ *max_variable_size = rsp_data->max_variable_size; out_free: - kfree(rsp_data); -out_free_req: - kfree(req_data); + qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma); out: return efi_status; } --- linux-xilinx-6.8.0.orig/drivers/firmware/qcom/qcom_scm.c +++ linux-xilinx-6.8.0/drivers/firmware/qcom/qcom_scm.c @@ -569,13 +569,14 @@ ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; desc.args[1] = mdata_phys; ret = qcom_scm_call(__scm->dev, &desc, &res); - qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); out: @@ -637,10 +638,12 @@ ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); return ret ? : res.result[0]; @@ -672,10 +675,12 @@ ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); return ret ? : res.result[0]; @@ -706,11 +711,12 @@ ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; ret = qcom_scm_call(__scm->dev, &desc, &res); - qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); return ret ? : res.result[0]; @@ -1576,9 +1582,9 @@ /** * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app. * @app_id: The ID of the target app. - * @req: Request buffer sent to the app (must be DMA-mappable). + * @req: DMA address of the request buffer sent to the app. * @req_size: Size of the request buffer. - * @rsp: Response buffer, written to by the app (must be DMA-mappable). + * @rsp: DMA address of the response buffer, written to by the app. * @rsp_size: Size of the response buffer. * * Sends a request to the QSEE app associated with the given ID and read back @@ -1589,33 +1595,13 @@ * * Return: Zero on success, nonzero on failure. */ -int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, - size_t rsp_size) +int qcom_scm_qseecom_app_send(u32 app_id, dma_addr_t req, size_t req_size, + dma_addr_t rsp, size_t rsp_size) { struct qcom_scm_qseecom_resp res = {}; struct qcom_scm_desc desc = {}; - dma_addr_t req_phys; - dma_addr_t rsp_phys; int status; - /* Map request buffer */ - req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE); - status = dma_mapping_error(__scm->dev, req_phys); - if (status) { - dev_err(__scm->dev, "qseecom: failed to map request buffer\n"); - return status; - } - - /* Map response buffer */ - rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE); - status = dma_mapping_error(__scm->dev, rsp_phys); - if (status) { - dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); - dev_err(__scm->dev, "qseecom: failed to map response buffer\n"); - return status; - } - - /* Set up SCM call data */ desc.owner = QSEECOM_TZ_OWNER_TZ_APPS; desc.svc = QSEECOM_TZ_SVC_APP_ID_PLACEHOLDER; desc.cmd = QSEECOM_TZ_CMD_APP_SEND; @@ -1623,18 +1609,13 @@ QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL); desc.args[0] = app_id; - desc.args[1] = req_phys; + desc.args[1] = req; desc.args[2] = req_size; - desc.args[3] = rsp_phys; + desc.args[3] = rsp; desc.args[4] = rsp_size; - /* Perform call */ status = qcom_scm_qseecom_call(&desc, &res); - /* Unmap buffers */ - dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE); - dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); - if (status) return status; @@ -1649,7 +1630,7 @@ * We do not yet support re-entrant calls via the qseecom interface. To prevent + any potential issues with this, only allow validated machines for now. */ -static const struct of_device_id qcom_scm_qseecom_allowlist[] = { +static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "lenovo,thinkpad-x13s", }, { } }; @@ -1738,7 +1719,7 @@ */ bool qcom_scm_is_available(void) { - return !!__scm; + return !!READ_ONCE(__scm); } EXPORT_SYMBOL_GPL(qcom_scm_is_available); @@ -1819,10 +1800,12 @@ if (!scm) return -ENOMEM; + scm->dev = &pdev->dev; ret = qcom_scm_find_dload_address(&pdev->dev, &scm->dload_mode_addr); if (ret < 0) return ret; + init_completion(&scm->waitq_comp); mutex_init(&scm->scm_bw_lock); scm->path = devm_of_icc_get(&pdev->dev, NULL); @@ -1854,10 +1837,8 @@ if (ret) return ret; - __scm = scm; - __scm->dev = &pdev->dev; - - init_completion(&__scm->waitq_comp); + /* Let all above stores be available after this */ + smp_store_release(&__scm, scm); irq = platform_get_irq_optional(pdev, 0); if (irq < 0) { --- linux-xilinx-6.8.0.orig/drivers/firmware/raspberrypi.c +++ linux-xilinx-6.8.0/drivers/firmware/raspberrypi.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -97,8 +98,8 @@ if (size & 3) return -EINVAL; - buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, - GFP_ATOMIC); + buf = dma_alloc_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), + &bus_addr, GFP_ATOMIC); if (!buf) return -ENOMEM; @@ -126,7 +127,7 @@ ret = -EINVAL; } - dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); + dma_free_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), buf, bus_addr); return ret; } --- linux-xilinx-6.8.0.orig/drivers/firmware/tegra/bpmp-debugfs.c +++ linux-xilinx-6.8.0/drivers/firmware/tegra/bpmp-debugfs.c @@ -77,7 +77,7 @@ root_path_buf = kzalloc(root_path_buf_len, GFP_KERNEL); if (!root_path_buf) - goto out; + return NULL; root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf, root_path_buf_len); --- linux-xilinx-6.8.0.orig/drivers/firmware/xilinx/Kconfig +++ linux-xilinx-6.8.0/drivers/firmware/xilinx/Kconfig @@ -23,4 +23,12 @@ Say yes to enable ZynqMP firmware interface debug APIs. If in doubt, say N. +config ZYNQMP_FIRMWARE_SECURE + bool "Enable Xilinx Zynq MPSoC secure firmware loading APIs" + help + Firmware secure driver is used as an interface to load + Authenticated and/or Encrypted firmware with single loadable + partition. Say yes to enable ZynqMP secure firmware loading + APIs.If in doubt, say N + endmenu --- linux-xilinx-6.8.0.orig/drivers/firmware/xilinx/Makefile +++ linux-xilinx-6.8.0/drivers/firmware/xilinx/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_ZYNQMP_FIRMWARE) += zynqmp.o obj-$(CONFIG_ZYNQMP_FIRMWARE_DEBUG) += zynqmp-debug.o +obj-$(CONFIG_ZYNQMP_FIRMWARE_SECURE) += zynqmp-secure.o --- linux-xilinx-6.8.0.orig/drivers/firmware/xilinx/zynqmp-debug.c +++ linux-xilinx-6.8.0/drivers/firmware/xilinx/zynqmp-debug.c @@ -2,7 +2,7 @@ /* * Xilinx Zynq MPSoC Firmware layer for debugfs APIs * - * Copyright (C) 2014-2018 Xilinx, Inc. + * Copyright (C) 2014-2021 Xilinx, Inc. * * Michal Simek * Davorin Mista @@ -31,13 +31,52 @@ #define PM_API(id) {id, #id, strlen(#id)} static struct pm_api_info pm_api_list[] = { + PM_API(PM_FORCE_POWERDOWN), + PM_API(PM_REQUEST_WAKEUP), + PM_API(PM_SYSTEM_SHUTDOWN), + PM_API(PM_REQUEST_NODE), + PM_API(PM_RELEASE_NODE), + PM_API(PM_SET_REQUIREMENT), PM_API(PM_GET_API_VERSION), + PM_API(PM_GET_NODE_STATUS), + PM_API(PM_REGISTER_NOTIFIER), + PM_API(PM_RESET_ASSERT), + PM_API(PM_RESET_GET_STATUS), + PM_API(PM_GET_CHIPID), + PM_API(PM_PINCTRL_SET_FUNCTION), + PM_API(PM_PINCTRL_CONFIG_PARAM_GET), + PM_API(PM_PINCTRL_CONFIG_PARAM_SET), + PM_API(PM_IOCTL), + PM_API(PM_CLOCK_ENABLE), + PM_API(PM_CLOCK_DISABLE), + PM_API(PM_CLOCK_GETSTATE), + PM_API(PM_CLOCK_SETDIVIDER), + PM_API(PM_CLOCK_GETDIVIDER), + PM_API(PM_CLOCK_SETPARENT), + PM_API(PM_CLOCK_GETPARENT), PM_API(PM_QUERY_DATA), }; static struct dentry *firmware_debugfs_root; /** + * zynqmp_pm_ioctl - PM IOCTL for device control and configs + * @node: Node ID of the device + * @ioctl: ID of the requested IOCTL + * @arg1: Argument 1 of requested IOCTL call + * @arg2: Argument 2 of requested IOCTL call + * @arg3: Argument 3 of requested IOCTL call + * @out: Returned output value + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_ioctl(const u32 node, const u32 ioctl, const u32 arg1, + const u32 arg2, const u32 arg3, u32 *out) +{ + return zynqmp_pm_invoke_fn(PM_IOCTL, out, 5, node, ioctl, arg1, arg2, arg3); +} + +/** * zynqmp_pm_argument_value() - Extract argument value from a PM-API request * @arg: Entered PM-API argument in string format * @@ -95,6 +134,139 @@ sprintf(debugfs_buf, "PM-API Version = %d.%d\n", pm_api_version >> 16, pm_api_version & 0xffff); break; + case PM_FORCE_POWERDOWN: + ret = zynqmp_pm_force_pwrdwn(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[1] : + ZYNQMP_PM_REQUEST_ACK_NO); + break; + case PM_REQUEST_WAKEUP: + ret = zynqmp_pm_request_wake(pm_api_arg[0], + pm_api_arg[1], pm_api_arg[2], + pm_api_arg[3] ? pm_api_arg[3] : + ZYNQMP_PM_REQUEST_ACK_NO); + break; + case PM_SYSTEM_SHUTDOWN: + ret = zynqmp_pm_system_shutdown(pm_api_arg[0], pm_api_arg[1]); + break; + case PM_REQUEST_NODE: + ret = zynqmp_pm_request_node(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[1] : + ZYNQMP_PM_CAPABILITY_ACCESS, + pm_api_arg[2] ? pm_api_arg[2] : 0, + pm_api_arg[3] ? pm_api_arg[3] : + ZYNQMP_PM_REQUEST_ACK_BLOCKING); + break; + case PM_RELEASE_NODE: + ret = zynqmp_pm_release_node(pm_api_arg[0]); + break; + case PM_SET_REQUIREMENT: + ret = zynqmp_pm_set_requirement(pm_api_arg[0], + pm_api_arg[1] ? pm_api_arg[1] : + ZYNQMP_PM_CAPABILITY_CONTEXT, + pm_api_arg[2] ? + pm_api_arg[2] : 0, + pm_api_arg[3] ? pm_api_arg[3] : + ZYNQMP_PM_REQUEST_ACK_BLOCKING); + break; + case PM_GET_NODE_STATUS: + ret = zynqmp_pm_get_node_status(pm_api_arg[0], + &pm_api_ret[0], + &pm_api_ret[1], + &pm_api_ret[2]); + if (!ret) + sprintf(debugfs_buf, + "GET_NODE_STATUS:\n\tNodeId: %llu\n\tStatus: %u\n\tRequirements: %u\n\tUsage: %u\n", + pm_api_arg[0], pm_api_ret[0], + pm_api_ret[1], pm_api_ret[2]); + break; + case PM_REGISTER_NOTIFIER: + ret = zynqmp_pm_register_notifier(pm_api_arg[0], + pm_api_arg[1] ? + pm_api_arg[1] : 0, + pm_api_arg[2] ? + pm_api_arg[2] : 0, + pm_api_arg[3] ? + pm_api_arg[3] : 0); + break; + case PM_RESET_ASSERT: + ret = zynqmp_pm_reset_assert(pm_api_arg[0], pm_api_arg[1]); + break; + case PM_RESET_GET_STATUS: + ret = zynqmp_pm_reset_get_status(pm_api_arg[0], &pm_api_ret[0]); + if (!ret) + sprintf(debugfs_buf, "Reset status: %u\n", + pm_api_ret[0]); + break; + case PM_GET_CHIPID: + ret = zynqmp_pm_get_chipid(&pm_api_ret[0], &pm_api_ret[1]); + if (!ret) + sprintf(debugfs_buf, "Idcode: %#x, Version:%#x\n", + pm_api_ret[0], pm_api_ret[1]); + break; + case PM_PINCTRL_SET_FUNCTION: + ret = zynqmp_pm_pinctrl_set_function(pm_api_arg[0], + pm_api_arg[1]); + break; + case PM_PINCTRL_CONFIG_PARAM_GET: + ret = zynqmp_pm_pinctrl_get_config(pm_api_arg[0], pm_api_arg[1], + &pm_api_ret[0]); + if (!ret) + sprintf(debugfs_buf, + "Pin: %llu, Param: %llu, Value: %u\n", + pm_api_arg[0], pm_api_arg[1], + pm_api_ret[0]); + break; + case PM_PINCTRL_CONFIG_PARAM_SET: + ret = zynqmp_pm_pinctrl_set_config(pm_api_arg[0], + pm_api_arg[1], + pm_api_arg[2]); + break; + case PM_IOCTL: + ret = zynqmp_pm_ioctl(pm_api_arg[0], pm_api_arg[1], + pm_api_arg[2], pm_api_arg[3], + pm_api_arg[4], &pm_api_ret[0]); + if (!ret && (pm_api_arg[1] == IOCTL_GET_RPU_OPER_MODE || + pm_api_arg[1] == IOCTL_GET_PLL_FRAC_MODE || + pm_api_arg[1] == IOCTL_GET_PLL_FRAC_DATA || + pm_api_arg[1] == IOCTL_READ_GGS || + pm_api_arg[1] == IOCTL_READ_PGGS || + pm_api_arg[1] == IOCTL_READ_REG)) + sprintf(debugfs_buf, "IOCTL return value: %u\n", + pm_api_ret[1]); + if (!ret && pm_api_arg[1] == IOCTL_GET_QOS) + sprintf(debugfs_buf, "Default QoS: %u\nCurrent QoS: %u\n", + pm_api_ret[1], pm_api_ret[2]); + break; + case PM_CLOCK_ENABLE: + ret = zynqmp_pm_clock_enable(pm_api_arg[0]); + break; + case PM_CLOCK_DISABLE: + ret = zynqmp_pm_clock_disable(pm_api_arg[0]); + break; + case PM_CLOCK_GETSTATE: + ret = zynqmp_pm_clock_getstate(pm_api_arg[0], &pm_api_ret[0]); + if (!ret) + sprintf(debugfs_buf, "Clock state: %u\n", + pm_api_ret[0]); + break; + case PM_CLOCK_SETDIVIDER: + ret = zynqmp_pm_clock_setdivider(pm_api_arg[0], pm_api_arg[1]); + break; + case PM_CLOCK_GETDIVIDER: + ret = zynqmp_pm_clock_getdivider(pm_api_arg[0], &pm_api_ret[0]); + if (!ret) + sprintf(debugfs_buf, "Divider Value: %d\n", + pm_api_ret[0]); + break; + case PM_CLOCK_SETPARENT: + ret = zynqmp_pm_clock_setparent(pm_api_arg[0], pm_api_arg[1]); + break; + case PM_CLOCK_GETPARENT: + ret = zynqmp_pm_clock_getparent(pm_api_arg[0], &pm_api_ret[0]); + if (!ret) + sprintf(debugfs_buf, + "Clock parent Index: %u\n", pm_api_ret[0]); + break; case PM_QUERY_DATA: qdata.qid = pm_api_arg[0]; qdata.arg1 = pm_api_arg[1]; @@ -150,7 +322,7 @@ char *kern_buff, *tmp_buff; char *pm_api_req; u32 pm_id = 0; - u64 pm_api_arg[4] = {0, 0, 0, 0}; + u64 pm_api_arg[5] = {0, 0, 0, 0, 0}; /* Return values from PM APIs calls */ u32 pm_api_ret[4] = {0, 0, 0, 0}; --- linux-xilinx-6.8.0.orig/drivers/firmware/xilinx/zynqmp-secure.c +++ linux-xilinx-6.8.0/drivers/firmware/xilinx/zynqmp-secure.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx ZynqMP SecureFw Driver. + * Copyright (c) 2018 Xilinx Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ZYNQMP_AES_KEY_SIZE 64 + +static u8 key[ZYNQMP_AES_KEY_SIZE] = {0}; +static dma_addr_t dma_addr; +static u8 *keyptr; +static size_t dma_size; +static char *kbuf; + +static ssize_t secure_load_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + const struct firmware *fw; + char image_name[NAME_MAX]; + u64 dst, ret; + int len; + + len = strscpy(image_name, buf, NAME_MAX - 1); + if (len > 0) { + if (image_name[len - 1] == '\n') + image_name[len - 1] = 0; + } else { + return -E2BIG; + } + + ret = request_firmware(&fw, image_name, dev); + if (ret) { + dev_err(dev, "Error requesting firmware %s\n", image_name); + return ret; + } + dma_size = fw->size; + + if (keyptr) + dma_size = fw->size + ZYNQMP_AES_KEY_SIZE; + + kbuf = dma_alloc_coherent(dev, dma_size, + &dma_addr, GFP_KERNEL); + if (!kbuf) { + release_firmware(fw); + return -ENOMEM; + } + + memcpy(kbuf, fw->data, fw->size); + + if (keyptr) + memcpy(kbuf + fw->size, key, ZYNQMP_AES_KEY_SIZE); + + /* To ensure cache coherency */ + caches_clean_inval_user_pou((unsigned long)kbuf, + (unsigned long)kbuf + dma_size); + + if (keyptr) + ret = zynqmp_pm_secure_load(dma_addr, dma_addr + fw->size, + &dst); + else + ret = zynqmp_pm_secure_load(dma_addr, 0, &dst); + + release_firmware(fw); + + if (ret) { + dev_info(dev, "Failed to load secure image \r\n"); + return ret; + } + dev_info(dev, "Verified image at 0x%llx\n", dst); + + return count; +} + +static ssize_t key_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, ZYNQMP_AES_KEY_SIZE + 1, "%s\n", key); +} + +static ssize_t key_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + memcpy(key, buf, count); + keyptr = &key[0]; + return count; +} + +static ssize_t secure_load_done_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + unsigned int value; + + ret = kstrtouint(buf, 10, &value); + if (ret) + return ret; + if (value) + dma_free_coherent(dev, dma_size, kbuf, dma_addr); + + return count; +} + +static DEVICE_ATTR_RW(key); +static DEVICE_ATTR_WO(secure_load); +static DEVICE_ATTR_WO(secure_load_done); + +static struct attribute *securefw_attrs[] = { + &dev_attr_secure_load_done.attr, + &dev_attr_secure_load.attr, + &dev_attr_key.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(securefw); + +static int securefw_probe(struct platform_device *pdev) +{ + int ret; + struct platform_device *securefw_pdev; + + securefw_pdev = pdev; + + securefw_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); + + ret = of_dma_configure(&securefw_pdev->dev, NULL, true); + if (ret < 0) { + dev_info(&securefw_pdev->dev, "Cannot setup DMA ops\r\n"); + return ret; + } + + ret = sysfs_create_groups(&securefw_pdev->dev.kobj, securefw_groups); + if (ret) + return ret; + + dev_info(&securefw_pdev->dev, "securefw probed\r\n"); + return ret; +} + +static int securefw_remove(struct platform_device *pdev) +{ + sysfs_remove_groups(&pdev->dev.kobj, securefw_groups); + return 0; +} + +static struct platform_driver securefw_driver = { + .driver = { + .name = "securefw", + }, + .probe = securefw_probe, + .remove = securefw_remove, +}; + +static struct platform_device *securefw_dev_reg; + +static int __init zynqmp_secure_init(void) +{ + int ret; + + ret = platform_driver_register(&securefw_driver); + if (ret) + return ret; + + securefw_dev_reg = platform_device_register_simple("securefw", -1, + NULL, 0); + if (IS_ERR(securefw_dev_reg)) { + ret = PTR_ERR(securefw_dev_reg); + platform_driver_unregister(&securefw_driver); + return ret; + } + return 0; +} + +static void __exit zynqmp_secure_exit(void) +{ + platform_device_unregister(securefw_dev_reg); + platform_driver_unregister(&securefw_driver); +} + +module_init(zynqmp_secure_init); +module_exit(zynqmp_secure_exit); --- linux-xilinx-6.8.0.orig/drivers/firmware/xilinx/zynqmp.c +++ linux-xilinx-6.8.0/drivers/firmware/xilinx/zynqmp.c @@ -3,6 +3,7 @@ * Xilinx Zynq MPSoC Firmware layer * * Copyright (C) 2014-2022 Xilinx, Inc. + * Copyright (C), 2022 - 2024 Advanced Micro Devices, Inc. * * Michal Simek * Davorin Mista @@ -13,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,19 +40,25 @@ /* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */ #define CRL_APB_BOOTPIN_CTRL_MASK 0xF0FU +/* firmware required uid buff size */ +#define UID_BUFF_SIZE 786 +#define UID_SET_LEN 4 +#define UID_LEN 4 + /* IOCTL/QUERY feature payload size */ #define FEATURE_PAYLOAD_SIZE 2 -/* Firmware feature check version mask */ -#define FIRMWARE_VERSION_MASK GENMASK(15, 0) - static bool feature_check_enabled; static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER); static u32 ioctl_features[FEATURE_PAYLOAD_SIZE]; static u32 query_features[FEATURE_PAYLOAD_SIZE]; +static u32 sip_svc_version; +static unsigned long register_address; static struct platform_device *em_dev; +static char image_name[NAME_MAX]; + /** * struct zynqmp_devinfo - Structure for Zynqmp device instance * @dev: Device Pointer @@ -153,6 +162,9 @@ ret_payload[1] = upper_32_bits(res.a0); ret_payload[2] = lower_32_bits(res.a1); ret_payload[3] = upper_32_bits(res.a1); + ret_payload[4] = lower_32_bits(res.a2); + ret_payload[5] = upper_32_bits(res.a2); + ret_payload[6] = lower_32_bits(res.a3); } return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); @@ -193,6 +205,9 @@ ret_payload[1] = upper_32_bits(res.a0); ret_payload[2] = lower_32_bits(res.a1); ret_payload[3] = upper_32_bits(res.a1); + ret_payload[4] = lower_32_bits(res.a2); + ret_payload[5] = upper_32_bits(res.a2); + ret_payload[6] = lower_32_bits(res.a3); } return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); @@ -220,11 +235,14 @@ * Feature check of TF-A APIs is done in the TF-A layer and it expects for * MODULE_ID_MASK bits of SMC's arg[0] to be the same as PM_MODULE_ID. */ - if (module_id == TF_A_MODULE_ID) + if (module_id == TF_A_MODULE_ID) { module_id = PM_MODULE_ID; + smc_arg[1] = api_id; + } else { + smc_arg[1] = (api_id & API_ID_MASK); + } smc_arg[0] = PM_SIP_SVC | FIELD_PREP(MODULE_ID_MASK, module_id) | feature_check_api_id; - smc_arg[1] = (api_id & API_ID_MASK); ret = do_fw_call(ret_payload, 2, smc_arg[0], smc_arg[1]); if (ret) @@ -334,6 +352,70 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_is_function_supported); /** + * zynqmp_pm_invoke_fw_fn() - Invoke the system-level platform management layer + * caller function depending on the configuration + * @pm_api_id: Requested PM-API call + * @ret_payload: Returned value array + * @num_args: Number of arguments to requested PM-API call + * + * Invoke platform management function for SMC or HVC call, depending on + * configuration. + * Following SMC Calling Convention (SMCCC) for SMC64: + * Pm Function Identifier, + * PM_SIP_SVC + PASS_THROUGH_FW_CMD_ID = + * ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) + * ((SMC_64) << FUNCID_CC_SHIFT) + * ((SIP_START) << FUNCID_OEN_SHIFT) + * (PASS_THROUGH_FW_CMD_ID)) + * + * PM_SIP_SVC - Registered ZynqMP SIP Service Call. + * PASS_THROUGH_FW_CMD_ID - Fixed SiP SVC call ID for FW specific calls. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_invoke_fw_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...) +{ + /* + * Added SIP service call Function Identifier + * Make sure to stay in x0 register + */ + u64 smc_arg[SMC_ARG_CNT_64]; + int ret, i; + va_list arg_list; + u32 args[SMC_ARG_CNT_32] = {0}; + u32 module_id; + + if (num_args > SMC_ARG_CNT_32) + return -EINVAL; + + va_start(arg_list, num_args); + + /* Check if feature is supported or not */ + ret = zynqmp_pm_feature(pm_api_id); + if (ret < 0) + return ret; + + for (i = 0; i < num_args; i++) + args[i] = va_arg(arg_list, u32); + + va_end(arg_list); + + module_id = FIELD_GET(PLM_MODULE_ID_MASK, pm_api_id); + + if (module_id == 0) + module_id = XPM_MODULE_ID; + + smc_arg[0] = PM_SIP_SVC | PASS_THROUGH_FW_CMD_ID; + smc_arg[1] = ((u64)args[0] << 32U) | FIELD_PREP(PLM_MODULE_ID_MASK, module_id) | + (pm_api_id & API_ID_MASK); + for (i = 1; i < (SMC_ARG_CNT_64 - 1); i++) + smc_arg[i + 1] = ((u64)args[(i * 2)] << 32U) | args[(i * 2) - 1]; + + return do_fw_call(ret_payload, 8, smc_arg[0], smc_arg[1], smc_arg[2], smc_arg[3], + smc_arg[4], smc_arg[5], smc_arg[6], smc_arg[7]); +} + +/** * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer * caller function depending on the configuration * @pm_api_id: Requested PM-API call @@ -491,6 +573,72 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_family_info); /** + * xlnx_get_crypto_dev_data() - Get crypto dev data of platform + * @feature_map: List of available feature map of all platform + * + * Return: Returns crypto dev data, either address crypto dev or ERR PTR + */ +void *xlnx_get_crypto_dev_data(struct xlnx_feature *feature_map) +{ + struct xlnx_feature *feature; + u32 v; + int ret; + + ret = zynqmp_pm_get_api_version(&v); + if (ret) + return ERR_PTR(ret); + + feature = feature_map; + for (; feature->family; feature++) { + if (feature->family == pm_family_code && + (feature->subfamily == ALL_SUB_FAMILY_CODE || + feature->subfamily == pm_sub_family_code)) { + if (feature->family == ZYNQMP_FAMILY_CODE || + feature->family == VERSAL_FAMILY_CODE) { + ret = zynqmp_pm_feature(feature->feature_id); + if (ret < 0) + return ERR_PTR(ret); + } else { + return ERR_PTR(-ENODEV); + } + + return feature->data; + } + } + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL_GPL(xlnx_get_crypto_dev_data); + +/** + * zynqmp_pm_get_sip_svc_version() - Get SiP service call version + * @version: Returned version value + * + * Return: Returns status, either success or error+reason + */ +static int zynqmp_pm_get_sip_svc_version(u32 *version) +{ + struct arm_smccc_res res; + u64 args[SMC_ARG_CNT_64] = {0}; + + if (!version) + return -EINVAL; + + /* Check if SiP SVC version already verified */ + if (sip_svc_version > 0) { + *version = sip_svc_version; + return 0; + } + + args[0] = GET_SIP_SVC_VERSION; + + arm_smccc_smc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res); + + *version = ((lower_32_bits(res.a0) << 16U) | lower_32_bits(res.a1)); + + return zynqmp_pm_ret_code(XST_PM_SUCCESS); +} + +/** * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version * @version: Returned version value * @@ -554,11 +702,34 @@ */ int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out) { - int ret; + int ret, i = 0; + u32 ret_payload[PAYLOAD_ARG_CNT] = {0}; + + if (sip_svc_version >= SIP_SVC_PASSTHROUGH_VERSION) { + ret = zynqmp_pm_invoke_fw_fn(PM_QUERY_DATA, ret_payload, 4, + qdata.qid, qdata.arg1, + qdata.arg2, qdata.arg3); + /* To support backward compatibility */ + if (!ret && !ret_payload[0]) { + /* + * TF-A passes return status on 0th index but + * api to get clock name reads data from 0th + * index so pass data at 0th index instead of + * return status + */ + if (qdata.qid == PM_QID_CLOCK_GET_NAME || + qdata.qid == PM_QID_PINCTRL_GET_FUNCTION_NAME) + i = 1; - ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, out, 4, qdata.qid, qdata.arg1, qdata.arg2, - qdata.arg3); + for (; i < PAYLOAD_ARG_CNT; i++, out++) + *out = ret_payload[i]; + return ret; + } + } + + ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, out, 4, qdata.qid, + qdata.arg1, qdata.arg2, qdata.arg3); /* * For clock name query, all bytes in SMC response are clock name * characters and return code is always success. For invalid clocks, @@ -833,6 +1004,63 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select); /** + * versal2_pm_ufs_get_txrx_cfgrdy() - API to read the UFS TX/RX Configuration ready + * + * @node_id: Node Id of the UFS device. + * @value: Tx/Rx configuration ready status information. + * + * This function read the UFS TX/RX Configuration ready status. + * + * Return: Returns status, either success or error+reason + */ +int versal2_pm_ufs_get_txrx_cfgrdy(u32 node_id, u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 2, node_id, IOCTL_UFS_TXRX_CFGRDY_GET); + *value = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(versal2_pm_ufs_get_txrx_cfgrdy); + +/** + * versal2_pm_ufs_sram_csr_sel() - API to read or write the UFS SRAM CSR register + * + * @node_id: Node Id of the UFS device. + * @type: read(0) or write(1) to SRAM CSR register. + * @value: SRAM CSR register information. + * + * This function read or write the UFS SRAM CSR register. + * + * Return: Returns status, either success or error+reason + */ +int versal2_pm_ufs_sram_csr_sel(u32 node_id, u32 type, u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + if (type == PM_UFS_SRAM_CSR_READ) { + ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 3, node_id, + IOCTL_UFS_SRAM_CSR_SEL, type); + *value = ret_payload[1]; + } else { + ret = zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node_id, IOCTL_UFS_SRAM_CSR_SEL, type, + *value); + } + + return ret; +} +EXPORT_SYMBOL_GPL(versal2_pm_ufs_sram_csr_sel); + +/** * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs) * @index: GGS register index * @value: Register value to be written @@ -900,6 +1128,25 @@ } EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass); +int zynqmp_pm_usb_set_state(u32 node, u32 state, u32 value) +{ + return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node, IOCTL_USB_SET_STATE, + state, value); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_usb_set_state); + +int zynqmp_pm_get_last_reset_reason(u32 *reset_reason) +{ + return zynqmp_pm_invoke_fn(PM_IOCTL, reset_reason, 2, 0, IOCTL_GET_LAST_RESET_REASON); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_last_reset_reason); + +int zynqmp_pm_afi(u32 index, u32 value) +{ + return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_AFI, index, value); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_afi); + /** * zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status * @value: Status value to be written @@ -915,6 +1162,26 @@ } /** + * zynqmp_pm_aie_operation - AI engine run time operations + * @node: AI engine node id + * @start_col: Starting column of AI partition + * @num_col: Number of column in AI partition + * @operation: ORed value of operations + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_aie_operation(u32 node, u16 start_col, u16 num_col, u32 operation) +{ + u32 partition; + + partition = num_col; + partition = ((partition << 16U) | start_col); + return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node, IOCTL_AIE_OPS, + partition, operation); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_aie_operation); + +/** * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) * @reset: Reset to be configured * @assert_flag: Flag stating should reset be asserted (1) or @@ -1014,17 +1281,13 @@ int zynqmp_pm_fpga_get_config_status(u32 *value) { u32 ret_payload[PAYLOAD_ARG_CNT]; - u32 buf, lower_addr, upper_addr; int ret; if (!value) return -EINVAL; - lower_addr = lower_32_bits((u64)&buf); - upper_addr = upper_32_bits((u64)&buf); - ret = zynqmp_pm_invoke_fn(PM_FPGA_READ, ret_payload, 4, - XILINX_ZYNQMP_PM_FPGA_CONFIG_STAT_OFFSET, lower_addr, upper_addr, + XILINX_ZYNQMP_PM_FPGA_CONFIG_STAT_OFFSET, 0, 0, XILINX_ZYNQMP_PM_FPGA_READ_CONFIG_REG); *value = ret_payload[1]; @@ -1034,6 +1297,56 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_config_status); /** + * zynqmp_pm_fpga_get_version -Get xilfpga component version info + * @value: Value to read + * + * This function provides access to the pmufw to get the xilfpga + * component version info. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_fpga_get_version(u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_VERSION, ret_payload, 0); + *value = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_version); + +/** + * zynqmp_pm_fpga_get_feature_list - Get xilfpga component supported feature + * list. + * @value: Value to read + * + * This function provides access to the pmufw to get the xilfpga component + * supported feature list. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_fpga_get_feature_list(u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_FEATURE_LIST, ret_payload, 0); + + *value = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_feature_list); + +/** * zynqmp_pm_pinctrl_request - Request Pin from firmware * @pin: Pin number to request * @@ -1120,8 +1433,11 @@ if (pm_family_code == ZYNQMP_FAMILY_CODE && param == PM_PINCTRL_CONFIG_TRI_STATE) { ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET); - if (ret < PM_PINCTRL_PARAM_SET_VERSION) + if (ret < PM_PINCTRL_PARAM_SET_VERSION) { + pr_warn("The requested pinctrl feature is not supported in the current firmware.\n" + "Expected firmware version is 2023.1 and above for this feature to work.\r\n"); return -EOPNOTSUPP; + } } return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, NULL, 3, pin, param, value); @@ -1182,6 +1498,193 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize); /** + * zynqmp_pm_bbram_write_aeskey - Write AES key in BBRAM + * @keylen: Size of the input key to be written + * @keyaddr: Address of a buffer which should contain the key + * to be written + * + * This function provides support to write AES keys into BBRAM. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_bbram_write_aeskey(u32 keylen, const u64 keyaddr) +{ + return zynqmp_pm_invoke_fn(PM_BBRAM_WRITE_KEY, NULL, 4, keylen, + lower_32_bits(keyaddr), + upper_32_bits(keyaddr)); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_bbram_write_aeskey); + +/** + * zynqmp_pm_bbram_write_usrdata - Write user data in BBRAM + * @data: User data to be written in BBRAM + * + * This function provides support to write user data into BBRAM. + * The size of the user data must be 4 bytes. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_bbram_write_usrdata(u32 data) +{ + return zynqmp_pm_invoke_fn(PM_BBRAM_WRITE_USERDATA, NULL, 1, data); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_bbram_write_usrdata); + +/** + * zynqmp_pm_bbram_read_usrdata - Read user data in BBRAM + * @outaddr: Address of a buffer to store the user data read from BBRAM + * + * This function provides support to read user data in BBRAM. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_bbram_read_usrdata(const u64 outaddr) +{ + return zynqmp_pm_invoke_fn(PM_BBRAM_READ_USERDATA, NULL, 1, outaddr); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_bbram_read_usrdata); + +/** + * zynqmp_pm_bbram_zeroize - Zeroizes AES key in BBRAM + * + * Description: + * This function provides support to zeroize AES key in BBRAM. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_bbram_zeroize(void) +{ + return zynqmp_pm_invoke_fn(PM_BBRAM_ZEROIZE, NULL, 0); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_bbram_zeroize); + +/** + * zynqmp_pm_bbram_lock_userdata - Locks user data for write + * + * Description: + * This function disables writing user data into BBRAM. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_bbram_lock_userdata(void) +{ + return zynqmp_pm_invoke_fn(PM_BBRAM_LOCK_USERDATA, NULL, 0); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_bbram_lock_userdata); + +/** + * zynqmp_pm_get_uid_info - It is used to get image Info List + * @address: Buffer address + * @size: Number of bytes required to read from the firmware. + * @count: Number of bytes read from the firmware. + * + * This function provides support to used to get image Info List + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_get_uid_info(const u64 address, const u32 size, u32 *count) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!count) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_GET_UID_INFO_LIST, ret_payload, 3, + upper_32_bits(address), + lower_32_bits(address), + size); + + *count = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_uid_info); + +/** + * zynqmp_pm_get_meta_header - It is used to get image meta header Info + * @src: PDI Image source buffer address. + * @dst: Meta-header destination buffer address + * @size: Size of the PDI image. + * @count: Number of bytes read from the firmware. + * + * This function provides a support to get the image meta header Info + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_get_meta_header(const u64 src, const u64 dst, + const u32 size, u32 *count) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!count) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_GET_META_HEADER_INFO_LIST, ret_payload, 5, + upper_32_bits(src), lower_32_bits(src), + upper_32_bits(dst), lower_32_bits(dst), + size); + + *count = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_meta_header); + +/** + * zynqmp_pm_fpga_read - Perform the fpga configuration readback + * @reg_numframes: Configuration register offset (or) Number of frames to read + * @phys_address: Physical Address of the buffer + * @readback_type: Type of fpga readback operation + * @value: Value to read + * + * This function provides access to xilfpga library to perform + * fpga configuration readback. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_fpga_read(const u32 reg_numframes, const u64 phys_address, + u32 readback_type, u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!value) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_FPGA_READ, ret_payload, 4, reg_numframes, + lower_32_bits(phys_address), + upper_32_bits(phys_address), + readback_type); + *value = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_read); + +/** + * zynqmp_pm_config_reg_access - PM Config API for Config register access + * @register_access_id: ID of the requested REGISTER_ACCESS + * @address: Address of the register to be accessed + * @mask: Mask to be written to the register + * @value: Value to be written to the register + * @out: Returned output value + * + * This function calls REGISTER_ACCESS to configure CSU/PMU registers. + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_config_reg_access(u32 register_access_id, u32 address, + u32 mask, u32 value, u32 *out) +{ + return zynqmp_pm_invoke_fn(PM_REGISTER_ACCESS, out, 4, + register_access_id, + address, mask, value); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_config_reg_access); + +/** * zynqmp_pm_set_suspend_mode() - Set system suspend mode * @mode: Mode to set for system suspend * @@ -1290,6 +1793,47 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config); /** + * zynqmp_pm_get_node_status - PM call to request a node's current power state + * @node: ID of the component or sub-system in question + * @status: Current operating state of the requested node + * @requirements: Current requirements asserted on the node, + * used for slave nodes only. + * @usage: Usage information, used for slave nodes only: + * PM_USAGE_NO_MASTER - No master is currently using + * the node + * PM_USAGE_CURRENT_MASTER - Only requesting master is + * currently using the node + * PM_USAGE_OTHER_MASTER - Only other masters are + * currently using the node + * PM_USAGE_BOTH_MASTERS - Both the current and at least + * one other master is currently + * using the node + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_get_node_status(const u32 node, u32 *const status, + u32 *const requirements, u32 *const usage) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!status) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_GET_NODE_STATUS, ret_payload, 1, node); + if (ret_payload[0] == XST_PM_SUCCESS) { + *status = ret_payload[1]; + if (requirements) + *requirements = ret_payload[2]; + if (usage) + *usage = ret_payload[3]; + } + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status); + +/** * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to * be powered down forcefully * @node: Node ID of the targeted PU or subsystem @@ -1355,8 +1899,16 @@ */ int zynqmp_pm_load_pdi(const u32 src, const u64 address) { - return zynqmp_pm_invoke_fn(PM_LOAD_PDI, NULL, 3, src, lower_32_bits(address), - upper_32_bits(address)); + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + ret = zynqmp_pm_invoke_fn(PM_LOAD_PDI, ret_payload, 3, src, + lower_32_bits(address), + upper_32_bits(address)); + if (ret_payload[0]) + return ret_payload[0]; + + return ret; } EXPORT_SYMBOL_GPL(zynqmp_pm_load_pdi); @@ -1385,6 +1937,263 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine); /** + * versal_pm_aes_key_write - Write AES key registers + * @keylen: Size of the input key to be written + * @keysrc: Key Source to be selected to which provided + * key should be updated + * @keyaddr: Address of a buffer which should contain the key + * to be written + * + * This function provides support to write AES volatile user keys. + * + * Return: Returns status, either success or error+reason + */ +int versal_pm_aes_key_write(const u32 keylen, + const u32 keysrc, const u64 keyaddr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_WRITE_KEY, NULL, 4, + keylen, keysrc, + lower_32_bits(keyaddr), + upper_32_bits(keyaddr)); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_key_write); + +/** + * versal_pm_aes_key_zero - Zeroise AES User key registers + * @keysrc: Key Source to be selected to which provided + * key should be updated + * + * This function provides support to zeroise AES volatile user keys. + * + * Return: Returns status, either success or error+reason + */ +int versal_pm_aes_key_zero(const u32 keysrc) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_KEY_ZERO, NULL, 1, keysrc); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_key_zero); + +/** + * versal_pm_efuse_read - Reads efuse. + * @address: Address of the payload + * @offset: Efuse offset + * @size: Size of data to be read + * + * This function provides support to read data from eFuse. + * + * Return: status, either success or error code. + */ +int versal_pm_efuse_read(const u64 address, u32 offset, u32 size) +{ + return zynqmp_pm_invoke_fn(PM_EFUSE_READ_VERSAL, NULL, 4, offset, + lower_32_bits(address), + upper_32_bits(address), size); +} +EXPORT_SYMBOL_GPL(versal_pm_efuse_read); + +/** + * versal_pm_efuse_write - Write efuse + * @address: Address of the payload + * @operationid: operationid which includes module and API id + * @envdis: Environment disable variable + * + * This function provides support to write data into eFuse. + * + * Return: status, either success or error+reason + */ +int versal_pm_efuse_write(const u64 address, const u32 operationid, + const u8 envdis) +{ + return zynqmp_pm_invoke_fn(operationid, NULL, 3, lower_32_bits(address), + upper_32_bits(address), envdis); +} +EXPORT_SYMBOL_GPL(versal_pm_efuse_write); + +/** + * versal_pm_aes_op_init - Init AES operation + * @hw_req: AES op init structure address + * + * This function provides support to init AES operation. + * + * Return: Returns status, either success or error+reason + */ +int versal_pm_aes_op_init(const u64 hw_req) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_OP_INIT, NULL, 2, + lower_32_bits(hw_req), + upper_32_bits(hw_req)); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_op_init); + +/** + * versal_pm_aes_update_aad - AES update aad + * @aad_addr: AES aad address + * @aad_len: AES aad data length + * + * This function provides support to update AAD data. + * + * Return: Returns status, either success or error+reason + */ +int versal_pm_aes_update_aad(const u64 aad_addr, const u32 aad_len) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_UPDATE_AAD, NULL, 3, + lower_32_bits(aad_addr), + upper_32_bits(aad_addr), + aad_len); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_update_aad); + +/** + * versal_pm_aes_enc_update - Access AES hardware to encrypt the data using + * AES-GCM core. + * @in_params: Address of the AesParams structure + * @in_addr: Address of input buffer + * + * Return: Returns status, either success or error code. + */ +int versal_pm_aes_enc_update(const u64 in_params, const u64 in_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_UPDATE, NULL, 4, + lower_32_bits(in_params), + upper_32_bits(in_params), + lower_32_bits(in_addr), + upper_32_bits(in_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_enc_update); + +/** + * versal_pm_aes_enc_final - Access AES hardware to store the GCM tag + * @gcm_addr: Address of the gcm tag + * + * Return: Returns status, either success or error code. + */ +int versal_pm_aes_enc_final(const u64 gcm_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_ENCRYPT_FINAL, NULL, 2, + lower_32_bits(gcm_addr), + upper_32_bits(gcm_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_enc_final); + +/** + * versal_pm_aes_dec_update - Access AES hardware to decrypt the data using + * AES-GCM core. + * @in_params: Address of the AesParams structure + * @in_addr: Address of input buffer + * + * Return: Returns status, either success or error code. + */ +int versal_pm_aes_dec_update(const u64 in_params, const u64 in_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_UPDATE, NULL, 4, + lower_32_bits(in_params), + upper_32_bits(in_params), + lower_32_bits(in_addr), + upper_32_bits(in_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_dec_update); + +/** + * versal_pm_aes_dec_final - Access AES hardware to get the GCM tag + * @gcm_addr: Address of the gcm tag + * + * Return: Returns status, either success or error code. + */ +int versal_pm_aes_dec_final(const u64 gcm_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_DECRYPT_FINAL, NULL, 2, + lower_32_bits(gcm_addr), + upper_32_bits(gcm_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_dec_final); + +/** + * versal_pm_aes_init - Init AES block + * + * This function initialise AES block. + * + * Return: Returns status, either success or error+reason + */ +int versal_pm_aes_init(void) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_AES_INIT, NULL, 0); +} +EXPORT_SYMBOL_GPL(versal_pm_aes_init); + +/** + * versal_pm_ecdsa_validate_key - Access ECDSA hardware to validate key + * @key_addr: Address of the key + * @curve_id: Type of ECC curve + * + * Return: Returns status, either success or error code. + */ +int versal_pm_ecdsa_validate_key(const u64 key_addr, const u32 curve_id) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_ELLIPTIC_VALIDATE_KEY, + NULL, 3, curve_id, + lower_32_bits(key_addr), + upper_32_bits(key_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_ecdsa_validate_key); + +/** + * versal_pm_ecdsa_verify_sign - Access ECDSA hardware to verify sign + * @sign_param_addr: Address of the sign params + * + * Return: Returns status, either success or error code. + */ +int versal_pm_ecdsa_verify_sign(const u64 sign_param_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_ELLIPTIC_VERIFY_SIGN, + NULL, 2, lower_32_bits(sign_param_addr), + upper_32_bits(sign_param_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_ecdsa_verify_sign); + +/** + * zynqmp_pm_efuse_access - Provides access to efuse memory. + * @address: Address of the efuse params structure + * @out: Returned output value + * + * Return: Returns status, either success or error code. + */ +int zynqmp_pm_efuse_access(const u64 address, u32 *out) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!out) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_EFUSE_ACCESS, ret_payload, 2, + upper_32_bits(address), + lower_32_bits(address)); + *out = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_efuse_access); + +int zynqmp_pm_secure_load(const u64 src_addr, u64 key_addr, u64 *dst) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret_value; + + if (!dst) + return -EINVAL; + + ret_value = zynqmp_pm_invoke_fn(PM_SECURE_IMAGE, ret_payload, 4, + lower_32_bits(src_addr), + upper_32_bits(src_addr), + lower_32_bits(key_addr), + upper_32_bits(key_addr)); + *dst = ((u64)ret_payload[1] << 32) | ret_payload[2]; + + return ret_value; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_secure_load); + +/** * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash * @address: Address of the data/ Address of output buffer where * hash should be stored. @@ -1410,6 +2219,78 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash); /** + * versal_pm_sha_hash - Access the SHA engine to calculate the hash + * @src: Address of the data + * @dst: Address of the output buffer + * @size: Size of the data. + * + * Return: Returns status, either success or error code. + */ +int versal_pm_sha_hash(const u64 src, const u64 dst, const u32 size) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_SHA3_UPDATE, NULL, 5, + lower_32_bits(src), upper_32_bits(src), + size, + lower_32_bits(dst), upper_32_bits(dst)); +} +EXPORT_SYMBOL_GPL(versal_pm_sha_hash); + +/** + * zynqmp_pm_rsa - Access RSA hardware to encrypt/decrypt the data with RSA. + * @address: Address of the data + * @size: Size of the data. + * @flags: + * BIT(0) - Encryption/Decryption + * 0 - RSA decryption with private key + * 1 - RSA encryption with public key. + * + * Return: Returns status, either success or error code. + */ +int zynqmp_pm_rsa(const u64 address, const u32 size, const u32 flags) +{ + u32 lower_32_bits = lower_32_bits(address); + u32 upper_32_bits = upper_32_bits(address); + + return zynqmp_pm_invoke_fn(PM_SECURE_RSA, NULL, 4, upper_32_bits, + lower_32_bits, size, flags); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_rsa); + +/** + * versal_pm_rsa_encrypt - Access RSA hardware to encrypt the data with RSA. + * @in_params: Address of the input parameter + * @in_addr: Address of input buffer + * + * Return: Returns status, either success or error code. + */ +int versal_pm_rsa_encrypt(const u64 in_params, const u64 in_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_RSA_PUBLIC_ENCRYPT, NULL, 4, + lower_32_bits(in_params), + upper_32_bits(in_params), + lower_32_bits(in_addr), + upper_32_bits(in_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_rsa_encrypt); + +/** + * versal_pm_rsa_decrypt - Access RSA hardware to decrypt the data with RSA. + * @in_params: Address of the input parameter + * @in_addr: Address of input buffer + * + * Return: Returns status, either success or error code. + */ +int versal_pm_rsa_decrypt(const u64 in_params, const u64 in_addr) +{ + return zynqmp_pm_invoke_fn(XSECURE_API_RSA_PRIVATE_DECRYPT, NULL, 4, + lower_32_bits(in_params), + upper_32_bits(in_params), + lower_32_bits(in_addr), + upper_32_bits(in_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_rsa_decrypt); + +/** * zynqmp_pm_register_notifier() - PM API for register a subsystem * to be notified about specific * event/error. @@ -1469,6 +2350,78 @@ } /** + * zynqmp_pm_sec_read_reg - PM call to securely read from given offset + * of the node + * @node_id: Node Id of the device + * @offset: Offset to be used (20-bit) + * @ret_value: Output data read from the given offset after + * firmware access policy is successfully enforced + * + * Return: Returns 0 on success or error value on failure + */ +int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + u32 count = 1; + int ret; + + if (!ret_value) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 4, node_id, IOCTL_READ_REG, + offset, count); + + *ret_value = ret_payload[1]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_sec_read_reg); + +/** + * zynqmp_pm_sec_mask_write_reg - PM call to securely write to given offset + * of the node + * @node_id: Node Id of the device + * @offset: Offset to be used (20-bit) + * @mask: Mask to be used + * @value: Value to be written + * + * Return: Returns 0 on success or error value on failure + */ +int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset, u32 mask, + u32 value) +{ + return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 5, node_id, IOCTL_MASK_WRITE_REG, + offset, mask, value); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_sec_mask_write_reg); + +/** + * zynqmp_pm_get_qos - PM call to query default and current QoS of the node + * @node: Node Id of the device + * @def_qos: Default QoS value + * @qos: Current QoS value + * + * Return: Returns 0 on success and the default and current QoS registers in + * @def_qos and @qos or error value on failure + */ +int zynqmp_pm_get_qos(u32 node, u32 *const def_qos, u32 *const qos) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!def_qos || !qos) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 2, node, IOCTL_GET_QOS); + + *def_qos = ret_payload[1]; + *qos = ret_payload[2]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_qos); + +/** * zynqmp_pm_set_sd_config - PM call to set value of SD config registers * @node: SD node ID * @config: The config type of SD registers @@ -1498,6 +2451,118 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_gem_config); /** + * zynqmp_pm_xilsem_cntrl_ops - PM call to perform XilSEM operations + * @cmd: Command for XilSEM scan control operations + * @response: Output response (command header, error code or status) + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_xilsem_cntrl_ops(u32 cmd, u32 *const response) +{ + u32 ret_buf[PAYLOAD_ARG_CNT]; + int ret; + + ret = zynqmp_pm_invoke_fn(PM_XSEM_HEADER | cmd, ret_buf, 0); + response[0] = ret_buf[1]; + response[1] = ret_buf[2]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_xilsem_cntrl_ops); + +/** + * zynqmp_pm_xilsem_cram_errinj - PM call to perform CRAM error injection + * @frame: Frame number to be used for error injection + * @qword: Word number to be used for error injection + * @bit: Bit location to be used for error injection + * @row: CFRAME row number to be used for error injection + * @response: Output response (command header, error code or status) + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_xilsem_cram_errinj(u32 frame, u32 qword, u32 bit, u32 row, + u32 *const response) +{ + u32 ret_buf[PAYLOAD_ARG_CNT]; + int ret; + + ret = zynqmp_pm_invoke_fn(PM_XSEM_CRAM_ERRINJ, ret_buf, 4, frame, + qword, bit, row); + response[0] = ret_buf[1]; + response[1] = ret_buf[2]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_xilsem_cram_errinj); + +int versal_pm_puf_registration(const u64 in_addr) +{ + return zynqmp_pm_invoke_fn(XPUF_API_PUF_REGISTRATION, NULL, + 2, lower_32_bits(in_addr), + upper_32_bits(in_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_puf_registration); + +int versal_pm_puf_clear_id(void) +{ + return zynqmp_pm_invoke_fn(XPUF_API_PUF_CLEAR_PUF_ID, NULL, + 2, NULL, NULL); +} +EXPORT_SYMBOL_GPL(versal_pm_puf_clear_id); + +int versal_pm_puf_regeneration(const u64 in_addr) +{ + return zynqmp_pm_invoke_fn(XPUF_API_PUF_REGENERATION, NULL, + 2, lower_32_bits(in_addr), + upper_32_bits(in_addr)); +} +EXPORT_SYMBOL_GPL(versal_pm_puf_regeneration); + +/** + * zynqmp_pm_xilsem_cram_readecc - PM call to perform CFRAME ECC read + * @frame: Frame number to be used for reading ECC + * @row: CFRAME row number to be used for reading ECC + * @response: Output response (status, Frame ecc header, ECC values) + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_xilsem_cram_readecc(u32 frame, u32 row, u32 *const response) +{ + u32 ret_buf[PAYLOAD_ARG_CNT]; + int ret; + + ret = zynqmp_pm_invoke_fn(PM_XSEM_CRAM_RD_ECC, ret_buf, 2, frame, row); + response[0] = ret_buf[0]; + response[1] = ret_buf[1]; + response[2] = ret_buf[2]; + response[3] = ret_buf[3]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_xilsem_cram_readecc); + +/** + * zynqmp_pm_xilsem_read_cfg - PM call to perform Xilsem configuration read + * @response: Output response (status, config header, Xilsem config) + * + * Return: Returns 0 on success or error value on failure. + */ +int zynqmp_pm_xilsem_read_cfg(u32 *const response) +{ + u32 ret_buf[PAYLOAD_ARG_CNT]; + int ret; + + ret = zynqmp_pm_invoke_fn(PM_XSEM_RD_CONFIG, ret_buf, 0); + response[0] = ret_buf[0]; + response[1] = ret_buf[1]; + response[2] = ret_buf[2]; + response[3] = ret_buf[3]; + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_xilsem_read_cfg); + +/** * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope * @subtype: Shutdown subtype * @name: Matching string for scope argument @@ -1837,6 +2902,56 @@ static DEVICE_ATTR_RW(feature_config_value); +static ssize_t last_reset_reason_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + ret = zynqmp_pm_get_last_reset_reason(ret_payload); + if (ret) + return ret; + + switch (ret_payload[1]) { + case PM_RESET_REASON_EXT_POR: + return sprintf(buf, "ext_por\n"); + case PM_RESET_REASON_SW_POR: + return sprintf(buf, "sw_por\n"); + case PM_RESET_REASON_SLR_POR: + return sprintf(buf, "slr_por\n"); + case PM_RESET_REASON_ERR_POR: + return sprintf(buf, "err_por\n"); + case PM_RESET_REASON_DAP_SRST: + return sprintf(buf, "dap_srst\n"); + case PM_RESET_REASON_ERR_SRST: + return sprintf(buf, "err_srst\n"); + case PM_RESET_REASON_SW_SRST: + return sprintf(buf, "sw_srst\n"); + case PM_RESET_REASON_SLR_SRST: + return sprintf(buf, "slr_srst\n"); + default: + return sprintf(buf, "unknown reset\n"); + } +} + +static DEVICE_ATTR_RO(last_reset_reason); + +static ssize_t firmware_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int len; + + len = strscpy(image_name, buf, NAME_MAX); + /* lose terminating \n */ + if (image_name[len - 1] == '\n') + image_name[len - 1] = 0; + + return count; +} +static DEVICE_ATTR_WO(firmware); + static struct attribute *zynqmp_firmware_attrs[] = { &dev_attr_ggs0.attr, &dev_attr_ggs1.attr, @@ -1850,11 +2965,252 @@ &dev_attr_health_status.attr, &dev_attr_feature_config_id.attr, &dev_attr_feature_config_value.attr, + &dev_attr_last_reset_reason.attr, + &dev_attr_firmware.attr, NULL, }; ATTRIBUTE_GROUPS(zynqmp_firmware); +/** + * config_reg_store - Write config_reg sysfs attribute + * @kobj: Kobject structure + * @attr: Kobject attribute structure + * @buf: User entered health_status attribute string + * @count: Buffer size + * + * User-space interface for setting the config register. + * + * To write any CSU/PMU register + * echo
> /sys/firmware/zynqmp/config_reg + * Usage: + * echo 0x345AB234 0xFFFFFFFF 0x1234ABCD > /sys/firmware/zynqmp/config_reg + * + * To Read any CSU/PMU register, write address to the variable like below + * echo
> /sys/firmware/zynqmp/config_reg + * + * Return: count argument if request succeeds, the corresponding error + * code otherwise + */ +static ssize_t config_reg_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *kern_buff, *inbuf, *tok; + unsigned long address, value, mask; + int ret; + + kern_buff = kzalloc(count + 1, GFP_KERNEL); + if (!kern_buff) + return -ENOMEM; + + ret = strscpy(kern_buff, buf, count + 1); + if (ret < 0) { + ret = -EFAULT; + goto err; + } + + inbuf = kern_buff; + + /* Read the addess */ + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + ret = kstrtol(tok, 16, &address); + if (ret) { + ret = -EFAULT; + goto err; + } + /* Read the write value */ + tok = strsep(&inbuf, " "); + /* + * If parameter provided is only address, then its a read operation. + * Store the address in a global variable and retrieve whenever + * required. + */ + if (!tok) { + register_address = address; + goto err; + } + register_address = address; + + ret = kstrtol(tok, 16, &mask); + if (ret) { + ret = -EFAULT; + goto err; + } + tok = strsep(&inbuf, " "); + if (!tok) { + ret = -EFAULT; + goto err; + } + ret = kstrtol(tok, 16, &value); + if (ret) { + ret = -EFAULT; + goto err; + } + ret = zynqmp_pm_config_reg_access(CONFIG_REG_WRITE, address, + mask, value, NULL); + if (ret) + pr_err("unable to write value to %lx\n", value); +err: + kfree(kern_buff); + if (ret) + return ret; + return count; +} + +/** + * config_reg_show - Read config_reg sysfs attribute + * @kobj: Kobject structure + * @attr: Kobject attribute structure + * @buf: User entered health_status attribute string + * + * User-space interface for getting the config register. + * + * To Read any CSU/PMU register, write address to the variable like below + * echo
> /sys/firmware/zynqmp/config_reg + * + * Then Read the address using below command + * cat /sys/firmware/zynqmp/config_reg + * + * Return: number of chars written to buf. + */ +static ssize_t config_reg_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + int ret; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + ret = zynqmp_pm_config_reg_access(CONFIG_REG_READ, register_address, + 0, 0, ret_payload); + if (ret) + return ret; + + return sprintf(buf, "0x%x\n", ret_payload[1]); +} + +static struct kobj_attribute zynqmp_attr_config_reg = + __ATTR_RW(config_reg); + +static struct attribute *attrs[] = { + &zynqmp_attr_config_reg.attr, + NULL, +}; + +static const struct attribute_group attr_group = { + .attrs = attrs, + NULL, +}; + +static int zynqmp_pm_sysfs_init(void) +{ + struct kobject *zynqmp_kobj; + int ret; + + zynqmp_kobj = kobject_create_and_add("zynqmp", firmware_kobj); + if (!zynqmp_kobj) { + pr_err("zynqmp: Firmware kobj add failed.\n"); + return -ENOMEM; + } + + ret = sysfs_create_group(zynqmp_kobj, &attr_group); + if (ret) { + pr_err("%s() sysfs creation fail with error %d\n", + __func__, ret); + } + + return ret; +} + +static ssize_t firmware_uid_get_data(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + struct device *kdev = kobj_to_dev(kobj); + dma_addr_t dma_addr = 0; + char *kbuf; + u32 size; + int ret; + + kbuf = dma_alloc_coherent(kdev, UID_BUFF_SIZE, &dma_addr, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + /* Read from the firmware memory */ + ret = zynqmp_pm_get_uid_info(dma_addr, UID_BUFF_SIZE, &size); + if (ret) { + dma_free_coherent(kdev, UID_BUFF_SIZE, kbuf, dma_addr); + return ret; + } + + size = size * UID_SET_LEN * UID_LEN; + memcpy(buf, kbuf, size); + dma_free_coherent(kdev, UID_BUFF_SIZE, kbuf, dma_addr); + + return size; +} + +static const struct bin_attribute uid_attr = { + .attr.name = "uid-read", + .attr.mode = 00400, + .size = 1, + .read = firmware_uid_get_data, +}; + +static ssize_t firmware_meta_header_get_data(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + struct device *kdev = kobj_to_dev(kobj); + const struct firmware *fw; + dma_addr_t dma_addr = 0; + char *kbuf; + u32 size; + int ret; + + ret = request_firmware(&fw, image_name, kdev); + if (ret) { + dev_err(kdev, "Error requesting firmware %s\n", image_name); + return ret; + } + + kbuf = dma_alloc_coherent(kdev, fw->size, &dma_addr, GFP_KERNEL); + if (!kbuf) { + ret = -ENOMEM; + goto free_firmware; + } + + memcpy(kbuf, fw->data, fw->size); + + /* Read from the firmware memory */ + ret = zynqmp_pm_get_meta_header(dma_addr, dma_addr, fw->size, &size); + if (ret) + goto free_dma; + + memcpy(buf, kbuf, size); + ret = size; + +free_dma: + dma_free_coherent(kdev, fw->size, kbuf, dma_addr); +free_firmware: + release_firmware(fw); + + return ret; +} + +static const struct bin_attribute meta_header_attr = { + .attr.name = "meta-header-read", + .attr.mode = 00400, + .size = 1, + .read = firmware_meta_header_get_data, +}; + static int zynqmp_firmware_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1865,6 +3221,11 @@ if (ret) return ret; + /* Get SiP SVC version number */ + ret = zynqmp_pm_get_sip_svc_version(&sip_svc_version); + if (ret) + return ret; + ret = do_feature_check_call(PM_FEATURE_CHECK); if (ret >= 0 && ((ret & FIRMWARE_VERSION_MASK) >= PM_API_VERSION_1)) feature_check_enabled = true; @@ -1918,11 +3279,37 @@ return ret; } + ret = zynqmp_pm_sysfs_init(); + if (ret) { + pr_err("%s() sysfs init fail with error %d\n", __func__, ret); + return ret; + } + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret < 0) { + dev_err(dev, "no usable DMA configuration"); + return ret; + } + + ret = sysfs_create_bin_file(&pdev->dev.kobj, &uid_attr); + if (ret) { + pr_err("%s() Failed to create sysfs binary file for uid-read with error%d\n", + __func__, ret); + return ret; + } + + ret = sysfs_create_bin_file(&pdev->dev.kobj, &meta_header_attr); + if (ret) { + dev_err(dev, "%s() Failed to create sysfs binary file for meta-header-read with error%d\n", + __func__, ret); + return ret; + } + zynqmp_pm_api_debugfs_init(); if (pm_family_code == VERSAL_FAMILY_CODE) { em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", - -1, NULL, 0); + -1, &pm_sub_family_code, 4); if (IS_ERR(em_dev)) dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n"); } --- linux-xilinx-6.8.0.orig/drivers/fpga/Kconfig +++ linux-xilinx-6.8.0/drivers/fpga/Kconfig @@ -12,6 +12,16 @@ if FPGA +config FPGA_MGR_DEBUG_FS + tristate "FPGA debug fs" + select DEBUG_FS + help + Say Y here if you want to expose a DebugFS interface for the + FPGA Manager Framework. FPGA manager DebugFS provides a user + interface to read the fpga specific configuration information. + + If unsure, say N. + config FPGA_MGR_SOCFPGA tristate "Altera SOCFPGA FPGA Manager" depends on ARCH_INTEL_SOCFPGA || COMPILE_TEST @@ -91,6 +101,24 @@ FPGA manager driver support for the Altera Cyclone II FPGA present on the TS-73xx SBC boards. +config FPGA_MGR_ZYNQ_AFI_FPGA + bool "Xilinx AFI FPGA" + depends on FPGA_MGR_ZYNQ_FPGA + help + Zynq AFI driver support for writing to the AFI registers + for configuring the PS_PL interface. For some of the bitstream + or designs to work the PS to PL interfaces need to be configured + like the data bus-width etc. + +config XILINX_AFI_FPGA + bool "Xilinx AFI FPGA" + depends on FPGA_MGR_ZYNQMP_FPGA || COMPILE_TEST + help + FPGA manager driver support for writing to the AFI registers + for configuring the PS_PL interface. For some of the bitstream + or designs to work the PS to PL interfaces need to be configured + like the datawidth etc. + config FPGA_BRIDGE tristate "FPGA Bridge Framework" help --- linux-xilinx-6.8.0.orig/drivers/fpga/Makefile +++ linux-xilinx-6.8.0/drivers/fpga/Makefile @@ -17,8 +17,10 @@ obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o obj-$(CONFIG_FPGA_MGR_XILINX_SPI) += xilinx-spi.o obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o +obj-$(CONFIG_FPGA_MGR_ZYNQ_AFI_FPGA) += zynq-afi.o obj-$(CONFIG_FPGA_MGR_ZYNQMP_FPGA) += zynqmp-fpga.o obj-$(CONFIG_FPGA_MGR_VERSAL_FPGA) += versal-fpga.o +obj-$(CONFIG_XILINX_AFI_FPGA) += xilinx-afi.o obj-$(CONFIG_FPGA_MGR_MICROCHIP_SPI) += microchip-spi.o obj-$(CONFIG_FPGA_MGR_LATTICE_SYSCONFIG) += lattice-sysconfig.o obj-$(CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI) += lattice-sysconfig-spi.o --- linux-xilinx-6.8.0.orig/drivers/fpga/dfl-pci.c +++ linux-xilinx-6.8.0/drivers/fpga/dfl-pci.c @@ -78,6 +78,7 @@ #define PCIE_DEVICE_ID_SILICOM_PAC_N5011 0x1001 #define PCIE_DEVICE_ID_INTEL_DFL 0xbcce /* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */ +#define PCIE_SUBDEVICE_ID_INTEL_D5005 0x138d #define PCIE_SUBDEVICE_ID_INTEL_N6000 0x1770 #define PCIE_SUBDEVICE_ID_INTEL_N6001 0x1771 #define PCIE_SUBDEVICE_ID_INTEL_C6100 0x17d4 @@ -102,6 +103,8 @@ {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),}, {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),}, {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL, + PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_D5005),}, + {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL, PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),}, {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF, PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),}, --- linux-xilinx-6.8.0.orig/drivers/fpga/fpga-bridge.c +++ linux-xilinx-6.8.0/drivers/fpga/fpga-bridge.c @@ -13,6 +13,12 @@ #include #include +/* For enabling manual bridge set(enable/disable) function */ +#ifdef CONFIG_DEBUG_KERNEL +#undef DEBUG +#define DEBUG +#endif + static DEFINE_IDA(fpga_bridge_ida); static const struct class fpga_bridge_class; @@ -55,33 +61,26 @@ } EXPORT_SYMBOL_GPL(fpga_bridge_disable); -static struct fpga_bridge *__fpga_bridge_get(struct device *dev, +static struct fpga_bridge *__fpga_bridge_get(struct device *bridge_dev, struct fpga_image_info *info) { struct fpga_bridge *bridge; - int ret = -ENODEV; - bridge = to_fpga_bridge(dev); + bridge = to_fpga_bridge(bridge_dev); bridge->info = info; - if (!mutex_trylock(&bridge->mutex)) { - ret = -EBUSY; - goto err_dev; - } + if (!mutex_trylock(&bridge->mutex)) + return ERR_PTR(-EBUSY); - if (!try_module_get(dev->parent->driver->owner)) - goto err_ll_mod; + if (!try_module_get(bridge->br_ops_owner)) { + mutex_unlock(&bridge->mutex); + return ERR_PTR(-ENODEV); + } dev_dbg(&bridge->dev, "get\n"); return bridge; - -err_ll_mod: - mutex_unlock(&bridge->mutex); -err_dev: - put_device(dev); - return ERR_PTR(ret); } /** @@ -98,13 +97,18 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node *np, struct fpga_image_info *info) { - struct device *dev; + struct fpga_bridge *bridge; + struct device *bridge_dev; - dev = class_find_device_by_of_node(&fpga_bridge_class, np); - if (!dev) + bridge_dev = class_find_device_by_of_node(&fpga_bridge_class, np); + if (!bridge_dev) return ERR_PTR(-ENODEV); - return __fpga_bridge_get(dev, info); + bridge = __fpga_bridge_get(bridge_dev, info); + if (IS_ERR(bridge)) + put_device(bridge_dev); + + return bridge; } EXPORT_SYMBOL_GPL(of_fpga_bridge_get); @@ -125,6 +129,7 @@ struct fpga_bridge *fpga_bridge_get(struct device *dev, struct fpga_image_info *info) { + struct fpga_bridge *bridge; struct device *bridge_dev; bridge_dev = class_find_device(&fpga_bridge_class, NULL, dev, @@ -132,7 +137,11 @@ if (!bridge_dev) return ERR_PTR(-ENODEV); - return __fpga_bridge_get(bridge_dev, info); + bridge = __fpga_bridge_get(bridge_dev, info); + if (IS_ERR(bridge)) + put_device(bridge_dev); + + return bridge; } EXPORT_SYMBOL_GPL(fpga_bridge_get); @@ -146,7 +155,7 @@ dev_dbg(&bridge->dev, "put\n"); bridge->info = NULL; - module_put(bridge->dev.parent->driver->owner); + module_put(bridge->br_ops_owner); mutex_unlock(&bridge->mutex); put_device(&bridge->dev); } @@ -308,26 +317,51 @@ static DEVICE_ATTR_RO(name); static DEVICE_ATTR_RO(state); +#ifdef DEBUG +static ssize_t set_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpga_bridge *bridge = to_fpga_bridge(dev); + long enable; + int ret; + + ret = kstrtol(buf, 16, &enable); + if (ret) + return ret; + + if (bridge->br_ops && bridge->br_ops->enable_set) + enable = bridge->br_ops->enable_set(bridge, !!enable); + + return count; +} +static DEVICE_ATTR_WO(set); +#endif + static struct attribute *fpga_bridge_attrs[] = { &dev_attr_name.attr, &dev_attr_state.attr, +#ifdef DEBUG + &dev_attr_set.attr, +#endif NULL, }; ATTRIBUTE_GROUPS(fpga_bridge); /** - * fpga_bridge_register - create and register an FPGA Bridge device + * __fpga_bridge_register - create and register an FPGA Bridge device * @parent: FPGA bridge device from pdev * @name: FPGA bridge name * @br_ops: pointer to structure of fpga bridge ops * @priv: FPGA bridge private data + * @owner: owner module containing the br_ops * * Return: struct fpga_bridge pointer or ERR_PTR() */ struct fpga_bridge * -fpga_bridge_register(struct device *parent, const char *name, - const struct fpga_bridge_ops *br_ops, - void *priv) +__fpga_bridge_register(struct device *parent, const char *name, + const struct fpga_bridge_ops *br_ops, + void *priv, struct module *owner) { struct fpga_bridge *bridge; int id, ret; @@ -357,6 +391,7 @@ bridge->name = name; bridge->br_ops = br_ops; + bridge->br_ops_owner = owner; bridge->priv = priv; bridge->dev.groups = br_ops->groups; @@ -386,7 +421,7 @@ return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(fpga_bridge_register); +EXPORT_SYMBOL_GPL(__fpga_bridge_register); /** * fpga_bridge_unregister - unregister an FPGA bridge --- linux-xilinx-6.8.0.orig/drivers/fpga/fpga-mgr.c +++ linux-xilinx-6.8.0/drivers/fpga/fpga-mgr.c @@ -8,6 +8,9 @@ * With code from the mailing list: * Copyright (C) 2013 Xilinx, Inc. */ +#include +#include +#include #include #include #include @@ -61,12 +64,14 @@ { int ret = 0; + mgr->err = 0; mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; if (mgr->mops->write_complete) ret = mgr->mops->write_complete(mgr, info); if (ret) { dev_err(&mgr->dev, "Error after writing image data to FPGA\n"); mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; + mgr->err = ret; return ret; } mgr->state = FPGA_MGR_STATE_OPERATING; @@ -272,6 +277,7 @@ size_t header_size = info->header_size; int ret; + mgr->err = 0; mgr->state = FPGA_MGR_STATE_WRITE_INIT; if (header_size > count) @@ -284,6 +290,7 @@ if (ret) { dev_err(&mgr->dev, "Error preparing FPGA for writing\n"); mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; + mgr->err = ret; return ret; } @@ -364,11 +371,15 @@ { int ret; + if (info->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) + memcpy(info->key, mgr->key, ENCRYPTED_KEY_LEN); + ret = fpga_mgr_prepare_sg(mgr, info, sgt); if (ret) return ret; /* Write the FPGA image to the FPGA. */ + mgr->err = 0; mgr->state = FPGA_MGR_STATE_WRITE; if (mgr->mops->write_sg) { ret = fpga_mgr_write_sg(mgr, sgt); @@ -405,6 +416,7 @@ if (ret) { dev_err(&mgr->dev, "Error while writing image data to FPGA\n"); mgr->state = FPGA_MGR_STATE_WRITE_ERR; + mgr->err = ret; return ret; } @@ -436,11 +448,13 @@ /* * Write the FPGA image to the FPGA. */ + mgr->err = 0; mgr->state = FPGA_MGR_STATE_WRITE; ret = fpga_mgr_write(mgr, buf, count); if (ret) { dev_err(&mgr->dev, "Error while writing image data to FPGA\n"); mgr->state = FPGA_MGR_STATE_WRITE_ERR; + mgr->err = ret; return ret; } @@ -519,6 +533,39 @@ return rc; } +static int fpga_dmabuf_load(struct fpga_manager *mgr, + struct fpga_image_info *info) +{ + struct dma_buf_attachment *attach; + struct sg_table *sgt; + int ret; + + /* create attachment for dmabuf with the user device */ + attach = dma_buf_attach(mgr->dmabuf, &mgr->dev); + if (IS_ERR(attach)) { + pr_err("failed to attach dmabuf\n"); + ret = PTR_ERR(attach); + goto fail_put; + } + + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + goto fail_detach; + } + + info->sgt = sgt; + ret = fpga_mgr_buf_load_sg(mgr, info, info->sgt); + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); + +fail_detach: + dma_buf_detach(mgr->dmabuf, attach); +fail_put: + dma_buf_put(mgr->dmabuf); + + return ret; +} + /** * fpga_mgr_firmware_load - request firmware and load to fpga * @mgr: fpga manager @@ -543,11 +590,17 @@ dev_info(dev, "writing %s to %s\n", image_name, mgr->name); + mgr->err = 0; mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ; + /* flags indicates whether to do full or partial reconfiguration */ + info->flags = mgr->flags; + memcpy(info->key, mgr->key, ENCRYPTED_KEY_LEN); + ret = request_firmware(&fw, image_name, dev); if (ret) { mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ_ERR; + mgr->err = ret; dev_err(dev, "Error requesting firmware %s\n", image_name); return ret; } @@ -573,6 +626,8 @@ { info->header_size = mgr->mops->initial_header_size; + if (mgr->flags & FPGA_MGR_CONFIG_DMA_BUF) + return fpga_dmabuf_load(mgr, info); if (info->sgt) return fpga_mgr_buf_load_sg(mgr, info, info->sgt); if (info->buf && info->count) @@ -626,6 +681,9 @@ { struct fpga_manager *mgr = to_fpga_manager(dev); + if (mgr->err) + return sprintf(buf, "%s: 0x%x\n", state_str[mgr->state], mgr->err); + return sprintf(buf, "%s\n", state_str[mgr->state]); } @@ -652,32 +710,102 @@ return len; } +static ssize_t firmware_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpga_manager *mgr = to_fpga_manager(dev); + unsigned int len; + char image_name[NAME_MAX]; + int ret; + + /* struct with information about the FPGA image to program. */ + struct fpga_image_info info = {0}; + + info.header_size = mgr->mops->initial_header_size; + + /* lose terminating \n */ + strcpy(image_name, buf); + len = strlen(image_name); + if (image_name[len - 1] == '\n') + image_name[len - 1] = 0; + + ret = fpga_mgr_firmware_load(mgr, &info, image_name); + if (ret) + return ret; + + return count; +} + +static ssize_t key_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fpga_manager *mgr = to_fpga_manager(dev); + + return snprintf(buf, ENCRYPTED_KEY_LEN + 1, "%s\n", mgr->key); +} + +static ssize_t key_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpga_manager *mgr = to_fpga_manager(dev); + + memcpy(mgr->key, buf, count); + + return count; +} + +static ssize_t flags_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fpga_manager *mgr = to_fpga_manager(dev); + + return sprintf(buf, "%lx\n", mgr->flags); +} + +static ssize_t flags_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fpga_manager *mgr = to_fpga_manager(dev); + int ret; + + ret = kstrtol(buf, 16, &mgr->flags); + if (ret) + return ret; + + return count; +} + static DEVICE_ATTR_RO(name); static DEVICE_ATTR_RO(state); static DEVICE_ATTR_RO(status); +static DEVICE_ATTR_WO(firmware); +static DEVICE_ATTR_RW(flags); +static DEVICE_ATTR_RW(key); static struct attribute *fpga_mgr_attrs[] = { &dev_attr_name.attr, &dev_attr_state.attr, &dev_attr_status.attr, + &dev_attr_firmware.attr, + &dev_attr_flags.attr, + &dev_attr_key.attr, NULL, }; ATTRIBUTE_GROUPS(fpga_mgr); -static struct fpga_manager *__fpga_mgr_get(struct device *dev) +static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev) { struct fpga_manager *mgr; - mgr = to_fpga_manager(dev); + mgr = to_fpga_manager(mgr_dev); - if (!try_module_get(dev->parent->driver->owner)) - goto err_dev; + if (!try_module_get(mgr->mops_owner)) + mgr = ERR_PTR(-ENODEV); return mgr; - -err_dev: - put_device(dev); - return ERR_PTR(-ENODEV); } static int fpga_mgr_dev_match(struct device *dev, const void *data) @@ -693,12 +821,18 @@ */ struct fpga_manager *fpga_mgr_get(struct device *dev) { - struct device *mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, - fpga_mgr_dev_match); + struct fpga_manager *mgr; + struct device *mgr_dev; + + mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, fpga_mgr_dev_match); if (!mgr_dev) return ERR_PTR(-ENODEV); - return __fpga_mgr_get(mgr_dev); + mgr = __fpga_mgr_get(mgr_dev); + if (IS_ERR(mgr)) + put_device(mgr_dev); + + return mgr; } EXPORT_SYMBOL_GPL(fpga_mgr_get); @@ -711,13 +845,18 @@ */ struct fpga_manager *of_fpga_mgr_get(struct device_node *node) { - struct device *dev; + struct fpga_manager *mgr; + struct device *mgr_dev; - dev = class_find_device_by_of_node(&fpga_mgr_class, node); - if (!dev) + mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node); + if (!mgr_dev) return ERR_PTR(-ENODEV); - return __fpga_mgr_get(dev); + mgr = __fpga_mgr_get(mgr_dev); + if (IS_ERR(mgr)) + put_device(mgr_dev); + + return mgr; } EXPORT_SYMBOL_GPL(of_fpga_mgr_get); @@ -727,11 +866,111 @@ */ void fpga_mgr_put(struct fpga_manager *mgr) { - module_put(mgr->dev.parent->driver->owner); + module_put(mgr->mops_owner); put_device(&mgr->dev); } EXPORT_SYMBOL_GPL(fpga_mgr_put); +#ifdef CONFIG_FPGA_MGR_DEBUG_FS +#include + +static int fpga_mgr_read(struct seq_file *s, void *data) +{ + struct fpga_manager *mgr = (struct fpga_manager *)s->private; + int ret = 0; + + if (!mgr->mops->read) + return -ENOENT; + + if (!mutex_trylock(&mgr->ref_mutex)) + return -EBUSY; + + if (mgr->state != FPGA_MGR_STATE_OPERATING) { + ret = -EPERM; + goto err_unlock; + } + + /* Read the FPGA configuration data from the fabric */ + ret = mgr->mops->read(mgr, s); + if (ret) + dev_err(&mgr->dev, "Error while reading configuration data from FPGA\n"); + +err_unlock: + mutex_unlock(&mgr->ref_mutex); + + return ret; +} + +static int fpga_mgr_read_open(struct inode *inode, struct file *file) +{ + return single_open(file, fpga_mgr_read, inode->i_private); +} + +static const struct file_operations fpga_mgr_ops_image = { + .owner = THIS_MODULE, + .open = fpga_mgr_read_open, + .read = seq_read, +}; +#endif + +static int fpga_dmabuf_fd_get(struct file *file, char __user *argp) +{ + struct fpga_manager *mgr = (struct fpga_manager *)(file->private_data); + int buffd; + + if (copy_from_user(&buffd, argp, sizeof(buffd))) + return -EFAULT; + + mgr->dmabuf = dma_buf_get(buffd); + if (IS_ERR_OR_NULL(mgr->dmabuf)) + return -EINVAL; + + mgr->flags = FPGA_MGR_CONFIG_DMA_BUF; + + return 0; +} + +static int fpga_device_open(struct inode *inode, struct file *file) +{ + struct miscdevice *miscdev = file->private_data; + struct fpga_manager *mgr = container_of(miscdev, + struct fpga_manager, miscdev); + + file->private_data = mgr; + + return 0; +} + +static int fpga_device_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static long fpga_device_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + char __user *argp = (char __user *)arg; + int err; + + switch (cmd) { + case FPGA_IOCTL_LOAD_DMA_BUFF: + err = fpga_dmabuf_fd_get(file, argp); + break; + default: + err = -ENOTTY; + } + + return err; +} + +static const struct file_operations fpga_fops = { + .owner = THIS_MODULE, + .open = fpga_device_open, + .release = fpga_device_release, + .unlocked_ioctl = fpga_device_ioctl, + .compat_ioctl = fpga_device_ioctl, +}; + /** * fpga_mgr_lock - Lock FPGA manager for exclusive use * @mgr: fpga manager @@ -766,9 +1005,10 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock); /** - * fpga_mgr_register_full - create and register an FPGA Manager device + * __fpga_mgr_register_full - create and register an FPGA Manager device * @parent: fpga manager device from pdev * @info: parameters for fpga manager + * @owner: owner module containing the ops * * The caller of this function is responsible for calling fpga_mgr_unregister(). * Using devm_fpga_mgr_register_full() instead is recommended. @@ -776,9 +1016,13 @@ * Return: pointer to struct fpga_manager pointer or ERR_PTR() */ struct fpga_manager * -fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info) +__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, + struct module *owner) { const struct fpga_manager_ops *mops = info->mops; +#ifdef CONFIG_FPGA_MGR_DEBUG_FS + struct dentry *d, *parent_dir; +#endif struct fpga_manager *mgr; int id, ret; @@ -804,6 +1048,8 @@ mutex_init(&mgr->ref_mutex); + mgr->mops_owner = owner; + mgr->name = info->name; mgr->mops = info->mops; mgr->priv = info->priv; @@ -815,10 +1061,28 @@ mgr->dev.of_node = parent->of_node; mgr->dev.id = id; + /* Make device dma capable by inheriting from parent's */ + set_dma_ops(&mgr->dev, get_dma_ops(parent)); + ret = dma_coerce_mask_and_coherent(&mgr->dev, dma_get_mask(parent)); + if (ret) { + dev_warn(parent, + "Failed to set DMA mask %llx. Trying to continue... %x\n", + dma_get_mask(parent), ret); + } + ret = dev_set_name(&mgr->dev, "fpga%d", id); if (ret) goto error_device; + mgr->miscdev.minor = MISC_DYNAMIC_MINOR; + mgr->miscdev.name = kobject_name(&mgr->dev.kobj); + mgr->miscdev.fops = &fpga_fops; + ret = misc_register(&mgr->miscdev); + if (ret) { + pr_err("fpga: failed to register misc device.\n"); + goto error_device; + } + /* * Initialize framework state by requesting low level driver read state * from device. FPGA may be in reset mode or may have been programmed @@ -832,6 +1096,28 @@ return ERR_PTR(ret); } +#ifdef CONFIG_FPGA_MGR_DEBUG_FS + mgr->dir = debugfs_create_dir("fpga", NULL); + if (!mgr->dir) + goto error_device; + + parent_dir = mgr->dir; + d = debugfs_create_dir(mgr->dev.kobj.name, parent_dir); + if (!d) { + debugfs_remove_recursive(parent_dir); + goto error_device; + } + + parent_dir = d; + d = debugfs_create_file("image", 0644, parent_dir, mgr, + &fpga_mgr_ops_image); + if (!d) { + debugfs_remove_recursive(mgr->dir); + goto error_device; + } +#endif + dev_info(&mgr->dev, "%s registered\n", mgr->name); + return mgr; error_device: @@ -841,14 +1127,15 @@ return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(__fpga_mgr_register_full); /** - * fpga_mgr_register - create and register an FPGA Manager device + * __fpga_mgr_register - create and register an FPGA Manager device * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data + * @owner: owner module containing the ops * * The caller of this function is responsible for calling fpga_mgr_unregister(). * Using devm_fpga_mgr_register() instead is recommended. This simple @@ -859,8 +1146,8 @@ * Return: pointer to struct fpga_manager pointer or ERR_PTR() */ struct fpga_manager * -fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv) +__fpga_mgr_register(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, void *priv, struct module *owner) { struct fpga_manager_info info = { 0 }; @@ -868,9 +1155,9 @@ info.mops = mops; info.priv = priv; - return fpga_mgr_register_full(parent, &info); + return __fpga_mgr_register_full(parent, &info, owner); } -EXPORT_SYMBOL_GPL(fpga_mgr_register); +EXPORT_SYMBOL_GPL(__fpga_mgr_register); /** * fpga_mgr_unregister - unregister an FPGA manager @@ -882,6 +1169,10 @@ { dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name); +#ifdef CONFIG_FPGA_MGR_DEBUG_FS + debugfs_remove_recursive(mgr->dir); +#endif + /* * If the low level driver provides a method for putting fpga into * a desired state upon unregister, do it. @@ -900,9 +1191,10 @@ } /** - * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register() + * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register() * @parent: fpga manager device from pdev * @info: parameters for fpga manager + * @owner: owner module containing the ops * * Return: fpga manager pointer on success, negative error code otherwise. * @@ -910,7 +1202,8 @@ * function will be called automatically when the managing device is detached. */ struct fpga_manager * -devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info) +__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info, + struct module *owner) { struct fpga_mgr_devres *dr; struct fpga_manager *mgr; @@ -919,7 +1212,7 @@ if (!dr) return ERR_PTR(-ENOMEM); - mgr = fpga_mgr_register_full(parent, info); + mgr = __fpga_mgr_register_full(parent, info, owner); if (IS_ERR(mgr)) { devres_free(dr); return mgr; @@ -930,14 +1223,15 @@ return mgr; } -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full); /** - * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() + * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data + * @owner: owner module containing the ops * * Return: fpga manager pointer on success, negative error code otherwise. * @@ -946,8 +1240,9 @@ * device is detached. */ struct fpga_manager * -devm_fpga_mgr_register(struct device *parent, const char *name, - const struct fpga_manager_ops *mops, void *priv) +__devm_fpga_mgr_register(struct device *parent, const char *name, + const struct fpga_manager_ops *mops, void *priv, + struct module *owner) { struct fpga_manager_info info = { 0 }; @@ -955,9 +1250,9 @@ info.mops = mops; info.priv = priv; - return devm_fpga_mgr_register_full(parent, &info); + return __devm_fpga_mgr_register_full(parent, &info, owner); } -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register); +EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register); static void fpga_mgr_dev_release(struct device *dev) { --- linux-xilinx-6.8.0.orig/drivers/fpga/fpga-region.c +++ linux-xilinx-6.8.0/drivers/fpga/fpga-region.c @@ -53,7 +53,7 @@ } get_device(dev); - if (!try_module_get(dev->parent->driver->owner)) { + if (!try_module_get(region->ops_owner)) { put_device(dev); mutex_unlock(®ion->mutex); return ERR_PTR(-ENODEV); @@ -75,7 +75,7 @@ dev_dbg(dev, "put\n"); - module_put(dev->parent->driver->owner); + module_put(region->ops_owner); put_device(dev); mutex_unlock(®ion->mutex); } @@ -181,14 +181,16 @@ ATTRIBUTE_GROUPS(fpga_region); /** - * fpga_region_register_full - create and register an FPGA Region device + * __fpga_region_register_full - create and register an FPGA Region device * @parent: device parent * @info: parameters for FPGA Region + * @owner: module containing the get_bridges function * * Return: struct fpga_region or ERR_PTR() */ struct fpga_region * -fpga_region_register_full(struct device *parent, const struct fpga_region_info *info) +__fpga_region_register_full(struct device *parent, const struct fpga_region_info *info, + struct module *owner) { struct fpga_region *region; int id, ret = 0; @@ -213,6 +215,7 @@ region->compat_id = info->compat_id; region->priv = info->priv; region->get_bridges = info->get_bridges; + region->ops_owner = owner; mutex_init(®ion->mutex); INIT_LIST_HEAD(®ion->bridge_list); @@ -241,13 +244,14 @@ return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(fpga_region_register_full); +EXPORT_SYMBOL_GPL(__fpga_region_register_full); /** - * fpga_region_register - create and register an FPGA Region device + * __fpga_region_register - create and register an FPGA Region device * @parent: device parent * @mgr: manager that programs this region * @get_bridges: optional function to get bridges to a list + * @owner: module containing the get_bridges function * * This simple version of the register function should be sufficient for most users. * The fpga_region_register_full() function is available for users that need to @@ -256,17 +260,17 @@ * Return: struct fpga_region or ERR_PTR() */ struct fpga_region * -fpga_region_register(struct device *parent, struct fpga_manager *mgr, - int (*get_bridges)(struct fpga_region *)) +__fpga_region_register(struct device *parent, struct fpga_manager *mgr, + int (*get_bridges)(struct fpga_region *), struct module *owner) { struct fpga_region_info info = { 0 }; info.mgr = mgr; info.get_bridges = get_bridges; - return fpga_region_register_full(parent, &info); + return __fpga_region_register_full(parent, &info, owner); } -EXPORT_SYMBOL_GPL(fpga_region_register); +EXPORT_SYMBOL_GPL(__fpga_region_register); /** * fpga_region_unregister - unregister an FPGA region --- linux-xilinx-6.8.0.orig/drivers/fpga/of-fpga-region.c +++ linux-xilinx-6.8.0/drivers/fpga/of-fpga-region.c @@ -230,6 +230,16 @@ if (of_property_read_bool(overlay, "encrypted-fpga-config")) info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM; + if (of_property_read_bool(overlay, "userkey-encrypted-fpga-config")) + info->flags |= FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM; + + if (of_property_read_bool(overlay, "ddrmem-authenticated-fpga-config")) + info->flags |= FPGA_MGR_DDR_MEM_AUTH_BITSTREAM; + + if (of_property_read_bool(overlay, + "securemem-authenticated-fpga-config")) + info->flags |= FPGA_MGR_SECURE_MEM_AUTH_BITSTREAM; + if (!of_property_read_string(overlay, "firmware-name", &firmware_name)) { info->firmware_name = devm_kstrdup(dev, firmware_name, --- linux-xilinx-6.8.0.orig/drivers/fpga/versal-fpga.c +++ linux-xilinx-6.8.0/drivers/fpga/versal-fpga.c @@ -19,6 +19,18 @@ return 0; } +static int versal_fpga_ops_write_sg(struct fpga_manager *mgr, + struct sg_table *sgt) +{ + dma_addr_t dma_addr; + int ret; + + dma_addr = sg_dma_address(sgt->sgl); + ret = zynqmp_pm_load_pdi(PDI_SRC_DDR, dma_addr); + + return ret; +} + static int versal_fpga_ops_write(struct fpga_manager *mgr, const char *buf, size_t size) { @@ -40,6 +52,7 @@ static const struct fpga_manager_ops versal_fpga_ops = { .write_init = versal_fpga_ops_write_init, .write = versal_fpga_ops_write, + .write_sg = versal_fpga_ops_write_sg, }; static int versal_fpga_probe(struct platform_device *pdev) --- linux-xilinx-6.8.0.orig/drivers/fpga/xilinx-afi.c +++ linux-xilinx-6.8.0/drivers/fpga/xilinx-afi.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx FPGA AFI bridge. + * Copyright (c) 2018 Xilinx Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct afi_fpga - AFI register description + * @value: value to be written to the register + * @regid: Register id for the register to be written + * @resets: Pointer to the reset control for ps-pl resets. + */ +struct afi_fpga { + u32 value; + u32 regid; + struct reset_control *resets; +}; + +static int afi_fpga_probe(struct platform_device *pdev) +{ + struct afi_fpga *afi_fpga; + struct device_node *np = pdev->dev.of_node; + int ret; + int i, entries, pairs; + u32 reg, val; + + afi_fpga = devm_kzalloc(&pdev->dev, sizeof(*afi_fpga), GFP_KERNEL); + if (!afi_fpga) + return -ENOMEM; + platform_set_drvdata(pdev, afi_fpga); + + /* Reset PL */ + afi_fpga->resets = devm_reset_control_array_get_optional_exclusive(&pdev->dev); + if (IS_ERR(afi_fpga->resets)) + return PTR_ERR(afi_fpga->resets); + + entries = of_property_count_u32_elems(np, "config-afi"); + if (!entries || (entries % 2)) { + dev_err(&pdev->dev, "Invalid number of registers\n"); + return -EINVAL; + } + pairs = entries / 2; + + for (i = 0; i < pairs; i++) { + ret = of_property_read_u32_index(np, "config-afi", i * 2, + ®); + if (ret) { + dev_err(&pdev->dev, "failed to read register\n"); + return -EINVAL; + } + ret = of_property_read_u32_index(np, "config-afi", i * 2 + 1, + &val); + if (ret) { + dev_err(&pdev->dev, "failed to read value\n"); + return -EINVAL; + } + ret = zynqmp_pm_afi(reg, val); + if (ret < 0) { + dev_err(&pdev->dev, "AFI register write error %d\n", + ret); + return ret; + } + } + + reset_control_reset(afi_fpga->resets); + + return 0; +} + +static const struct of_device_id afi_fpga_ids[] = { + { .compatible = "xlnx,afi-fpga" }, + { }, +}; +MODULE_DEVICE_TABLE(of, afi_fpga_ids); + +static struct platform_driver afi_fpga_driver = { + .driver = { + .name = "afi-fpga", + .of_match_table = afi_fpga_ids, + }, + .probe = afi_fpga_probe, +}; +module_platform_driver(afi_fpga_driver); + +MODULE_DESCRIPTION("FPGA afi module"); +MODULE_AUTHOR("Shubhrajyoti Datta "); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/fpga/zynq-afi.c +++ linux-xilinx-6.8.0/drivers/fpga/zynq-afi.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx FPGA AFI driver. + * Copyright (c) 2018 Xilinx Inc. + */ + +#include +#include +#include +#include +#include + +/* Registers and special values for doing register-based operations */ +#define AFI_RDCHAN_CTRL_OFFSET 0x00 +#define AFI_WRCHAN_CTRL_OFFSET 0x14 + +#define AFI_BUSWIDTH_MASK 0x01 + +/** + * struct afi_fpga - AFI register description + * @membase: pointer to register struct + * @afi_width: AFI bus width to be written + */ +struct zynq_afi_fpga { + void __iomem *membase; + u32 afi_width; +}; + +static int zynq_afi_fpga_probe(struct platform_device *pdev) +{ + struct zynq_afi_fpga *afi_fpga; + struct resource *res; + u32 reg_val; + u32 val; + + afi_fpga = devm_kzalloc(&pdev->dev, sizeof(*afi_fpga), GFP_KERNEL); + if (!afi_fpga) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + afi_fpga->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(afi_fpga->membase)) + return PTR_ERR(afi_fpga->membase); + + val = device_property_read_u32(&pdev->dev, "xlnx,afi-width", + &afi_fpga->afi_width); + if (val) { + dev_err(&pdev->dev, "Fail to get the afi bus width\n"); + return -EINVAL; + } + + reg_val = readl(afi_fpga->membase + AFI_RDCHAN_CTRL_OFFSET); + reg_val &= ~AFI_BUSWIDTH_MASK; + writel(reg_val | afi_fpga->afi_width, + afi_fpga->membase + AFI_RDCHAN_CTRL_OFFSET); + reg_val = readl(afi_fpga->membase + AFI_WRCHAN_CTRL_OFFSET); + reg_val &= ~AFI_BUSWIDTH_MASK; + writel(reg_val | afi_fpga->afi_width, + afi_fpga->membase + AFI_WRCHAN_CTRL_OFFSET); + + return 0; +} + +static const struct of_device_id zynq_afi_fpga_ids[] = { + { .compatible = "xlnx,zynq-afi-fpga" }, + { }, +}; +MODULE_DEVICE_TABLE(of, zynq_afi_fpga_ids); + +static struct platform_driver zynq_afi_fpga_driver = { + .driver = { + .name = "zynq-afi-fpga", + .of_match_table = zynq_afi_fpga_ids, + }, + .probe = zynq_afi_fpga_probe, +}; +module_platform_driver(zynq_afi_fpga_driver); + +MODULE_DESCRIPTION("ZYNQ FPGA AFI module"); +MODULE_AUTHOR("Nava kishore Manne "); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/fpga/zynqmp-fpga.c +++ linux-xilinx-6.8.0/drivers/fpga/zynqmp-fpga.c @@ -9,20 +9,85 @@ #include #include #include +#include #include #include /* Constant Definitions */ #define IXR_FPGA_DONE_MASK BIT(3) +#define READ_DMA_SIZE 0x200 +#define DUMMY_FRAMES_SIZE 0x64 +#define DUMMY_PAD_BYTE 0xFF +#define FPGA_WORD_SIZE 4 + +#define XILINX_ZYNQMP_PM_FPGA_READ_BACK BIT(6) +#define XILINX_ZYNQMP_PM_FPGA_REG_READ_BACK BIT(7) + +#define DEFAULT_FEATURE_LIST (XILINX_ZYNQMP_PM_FPGA_FULL | \ + XILINX_ZYNQMP_PM_FPGA_PARTIAL | \ + XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_DDR | \ + XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_OCM | \ + XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_USERKEY | \ + XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_DEVKEY | \ + XILINX_ZYNQMP_PM_FPGA_READ_BACK | \ + XILINX_ZYNQMP_PM_FPGA_REG_READ_BACK) + +static bool readback_type; +module_param(readback_type, bool, 0644); +MODULE_PARM_DESC(readback_type, + "readback_type 0-configuration register read " + "1- configuration data read (default: 0)"); + +/** + * struct zynqmp_configreg - Configuration register offsets + * @reg: Name of the configuration register. + * @offset: Register offset. + */ +struct zynqmp_configreg { + char *reg; + u32 offset; +}; + +static struct zynqmp_configreg cfgreg[] = { + {.reg = "CRC", .offset = 0}, + {.reg = "FAR", .offset = 1}, + {.reg = "FDRI", .offset = 2}, + {.reg = "FDRO", .offset = 3}, + {.reg = "CMD", .offset = 4}, + {.reg = "CTRL0", .offset = 5}, + {.reg = "MASK", .offset = 6}, + {.reg = "STAT", .offset = 7}, + {.reg = "LOUT", .offset = 8}, + {.reg = "COR0", .offset = 9}, + {.reg = "MFWR", .offset = 10}, + {.reg = "CBC", .offset = 11}, + {.reg = "IDCODE", .offset = 12}, + {.reg = "AXSS", .offset = 13}, + {.reg = "COR1", .offset = 14}, + {.reg = "WBSTR", .offset = 16}, + {.reg = "TIMER", .offset = 17}, + {.reg = "BOOTSTS", .offset = 22}, + {.reg = "CTRL1", .offset = 24}, + {} +}; + /** * struct zynqmp_fpga_priv - Private data structure * @dev: Device data structure + * @feature_list: Firmware supported feature list + * @version: Firmware version info. The higher 16 bytes belong to + * the major version number and the lower 16 bytes belong + * to a minor version number. * @flags: flags which is used to identify the bitfile type + * @size: Size of the Bit-stream used for readback */ struct zynqmp_fpga_priv { struct device *dev; + u32 feature_list; + u32 version; u32 flags; + u32 size; }; static int zynqmp_fpga_ops_write_init(struct fpga_manager *mgr, @@ -30,10 +95,27 @@ const char *buf, size_t size) { struct zynqmp_fpga_priv *priv; + int eemi_flags = 0; priv = mgr->priv; priv->flags = info->flags; + /* Update firmware flags */ + if (priv->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_USERKEY; + else if (priv->flags & FPGA_MGR_ENCRYPTED_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_DEVKEY; + if (priv->flags & FPGA_MGR_DDR_MEM_AUTH_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_DDR; + else if (priv->flags & FPGA_MGR_SECURE_MEM_AUTH_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_OCM; + if (priv->flags & FPGA_MGR_PARTIAL_RECONFIG) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_PARTIAL; + + /* Validate user flgas with firmware feature list */ + if ((priv->feature_list & eemi_flags) != eemi_flags) + return -EINVAL; + return 0; } @@ -41,27 +123,116 @@ const char *buf, size_t size) { struct zynqmp_fpga_priv *priv; + int word_align, ret, index; dma_addr_t dma_addr; u32 eemi_flags = 0; + size_t dma_size; char *kbuf; - int ret; priv = mgr->priv; + word_align = size % FPGA_WORD_SIZE; + if (word_align) + word_align = FPGA_WORD_SIZE - word_align; + + size = size + word_align; + priv->size = size; + + if (priv->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) + dma_size = size + ENCRYPTED_KEY_LEN; + else + dma_size = size; - kbuf = dma_alloc_coherent(priv->dev, size, &dma_addr, GFP_KERNEL); + kbuf = dma_alloc_coherent(priv->dev, dma_size, &dma_addr, GFP_KERNEL); if (!kbuf) return -ENOMEM; - memcpy(kbuf, buf, size); + for (index = 0; index < word_align; index++) + kbuf[index] = DUMMY_PAD_BYTE; + + memcpy(&kbuf[index], buf, size - index); + + if (priv->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) { + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_USERKEY; + memcpy(kbuf + size, mgr->key, ENCRYPTED_KEY_LEN); + } else if (priv->flags & FPGA_MGR_ENCRYPTED_BITSTREAM) { + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_DEVKEY; + } wmb(); /* ensure all writes are done before initiate FW call */ + if (priv->flags & FPGA_MGR_DDR_MEM_AUTH_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_DDR; + else if (priv->flags & FPGA_MGR_SECURE_MEM_AUTH_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_OCM; + if (priv->flags & FPGA_MGR_PARTIAL_RECONFIG) eemi_flags |= XILINX_ZYNQMP_PM_FPGA_PARTIAL; - ret = zynqmp_pm_fpga_load(dma_addr, size, eemi_flags); + if (priv->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) + ret = zynqmp_pm_fpga_load(dma_addr, dma_addr + size, + eemi_flags); + else + ret = zynqmp_pm_fpga_load(dma_addr, size, eemi_flags); + + dma_free_coherent(priv->dev, dma_size, kbuf, dma_addr); + + return ret; +} + +static unsigned long zynqmp_fpga_get_contiguous_size(struct sg_table *sgt) +{ + dma_addr_t expected = sg_dma_address(sgt->sgl); + unsigned long size = 0; + struct scatterlist *s; + unsigned int i; + + for_each_sg(sgt->sgl, s, sgt->nents, i) { + if (sg_dma_address(s) != expected) + break; + expected = sg_dma_address(s) + sg_dma_len(s); + size += sg_dma_len(s); + } + + return size; +} + +static int zynqmp_fpga_ops_write_sg(struct fpga_manager *mgr, + struct sg_table *sgt) +{ + dma_addr_t dma_addr, key_addr = 0; + struct zynqmp_fpga_priv *priv; + unsigned long contig_size; + u32 eemi_flags = 0; + char *kbuf; + int ret; + + priv = mgr->priv; - dma_free_coherent(priv->dev, size, kbuf, dma_addr); + dma_addr = sg_dma_address(sgt->sgl); + contig_size = zynqmp_fpga_get_contiguous_size(sgt); + + if (priv->flags & FPGA_MGR_PARTIAL_RECONFIG) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_PARTIAL; + if (priv->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_USERKEY; + else if (priv->flags & FPGA_MGR_ENCRYPTED_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_ENCRYPTION_DEVKEY; + if (priv->flags & FPGA_MGR_DDR_MEM_AUTH_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_DDR; + else if (priv->flags & FPGA_MGR_SECURE_MEM_AUTH_BITSTREAM) + eemi_flags |= XILINX_ZYNQMP_PM_FPGA_AUTHENTICATION_OCM; + + if (priv->flags & FPGA_MGR_USERKEY_ENCRYPTED_BITSTREAM) { + kbuf = dma_alloc_coherent(priv->dev, ENCRYPTED_KEY_LEN, + &key_addr, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + memcpy(kbuf, mgr->key, ENCRYPTED_KEY_LEN); + ret = zynqmp_pm_fpga_load(dma_addr, key_addr, eemi_flags); + dma_free_coherent(priv->dev, ENCRYPTED_KEY_LEN, kbuf, key_addr); + } else { + ret = zynqmp_pm_fpga_load(dma_addr, contig_size, eemi_flags); + } return ret; } @@ -97,10 +268,98 @@ }; ATTRIBUTE_GROUPS(zynqmp_fpga); +static int zynqmp_fpga_read_cfgreg(struct fpga_manager *mgr, + struct seq_file *s) +{ + int ret = 0; + u32 val; + unsigned int *buf; + dma_addr_t dma_addr = 0; + struct zynqmp_fpga_priv *priv; + struct zynqmp_configreg *p = cfgreg; + + priv = mgr->priv; + + if (!(priv->feature_list & XILINX_ZYNQMP_PM_FPGA_READ_BACK)) + return -EINVAL; + + buf = dma_alloc_coherent(mgr->dev.parent, READ_DMA_SIZE, + &dma_addr, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + seq_puts(s, "zynqMP FPGA Configuration register contents are\n"); + + while (p->reg) { + ret = zynqmp_pm_fpga_read(p->offset, dma_addr, readback_type, + &val); + if (ret) + goto free_dmabuf; + seq_printf(s, "%s --> \t %x \t\r\n", p->reg, val); + p++; + } + +free_dmabuf: + dma_free_coherent(mgr->dev.parent, READ_DMA_SIZE, buf, + dma_addr); + + return ret; +} + +static int zynqmp_fpga_read_cfgdata(struct fpga_manager *mgr, + struct seq_file *s) +{ + struct zynqmp_fpga_priv *priv; + int ret; + u32 data_offset; + unsigned int *buf; + dma_addr_t dma_addr = 0; + size_t size; + + priv = mgr->priv; + + if (!(priv->feature_list & XILINX_ZYNQMP_PM_FPGA_REG_READ_BACK)) + return -EINVAL; + + size = priv->size + READ_DMA_SIZE + DUMMY_FRAMES_SIZE; + + buf = dma_alloc_coherent(mgr->dev.parent, size, &dma_addr, + GFP_KERNEL); + if (!buf) + return -ENOMEM; + + seq_puts(s, "zynqMP FPGA Configuration data contents are\n"); + ret = zynqmp_pm_fpga_read((priv->size + DUMMY_FRAMES_SIZE) / 4, + dma_addr, readback_type, &data_offset); + if (ret) + goto free_dmabuf; + + seq_write(s, &buf[data_offset], priv->size); + +free_dmabuf: + dma_free_coherent(mgr->dev.parent, size, buf, dma_addr); + + return ret; +} + +static int zynqmp_fpga_ops_read(struct fpga_manager *mgr, struct seq_file *s) +{ + int ret; + + if (readback_type) + ret = zynqmp_fpga_read_cfgdata(mgr, s); + else + ret = zynqmp_fpga_read_cfgreg(mgr, s); + + return ret; +} + static const struct fpga_manager_ops zynqmp_fpga_ops = { .state = zynqmp_fpga_ops_state, .write_init = zynqmp_fpga_ops_write_init, .write = zynqmp_fpga_ops_write, + .write_sg = zynqmp_fpga_ops_write_sg, + .read = zynqmp_fpga_ops_read, }; static int zynqmp_fpga_probe(struct platform_device *pdev) @@ -115,6 +374,13 @@ priv->dev = dev; + if (!(zynqmp_pm_fpga_get_version(&priv->version))) { + if (zynqmp_pm_fpga_get_feature_list(&priv->feature_list)) + priv->feature_list = DEFAULT_FEATURE_LIST; + } else { + priv->feature_list = DEFAULT_FEATURE_LIST; + } + mgr = devm_fpga_mgr_register(dev, "Xilinx ZynqMP FPGA Manager", &zynqmp_fpga_ops, priv); return PTR_ERR_OR_ZERO(mgr); --- linux-xilinx-6.8.0.orig/drivers/gpio/Kconfig +++ linux-xilinx-6.8.0/drivers/gpio/Kconfig @@ -711,7 +711,8 @@ Say yes here to support UniPhier GPIOs. config GPIO_VF610 - def_bool y + bool "VF610 GPIO support" + default y if SOC_VF610 depends on ARCH_MXC select GPIOLIB_IRQCHIP help @@ -1526,7 +1527,7 @@ are "output only" GPIOs. config GPIO_TQMX86 - tristate "TQ-Systems QTMX86 GPIO" + tristate "TQ-Systems TQMx86 GPIO" depends on MFD_TQMX86 || COMPILE_TEST depends on HAS_IOPORT_MAP select GPIOLIB_IRQCHIP @@ -1586,6 +1587,18 @@ menu "PCI GPIO expanders" depends on PCI +config GPIO_AAEON + tristate "AAEON GPIO support" + depends on ASUS_WMI + depends on UBUNTU_ODM_DRIVERS + select MFD_AAEON + help + Say yes here to support GPIO pins on Single Board Computers produced + by AAEON. + + This driver leverages the ASUS WMI interface to access device + resources. + config GPIO_AMD8111 tristate "AMD 8111 GPIO driver" depends on X86 || COMPILE_TEST --- linux-xilinx-6.8.0.orig/drivers/gpio/Makefile +++ linux-xilinx-6.8.0/drivers/gpio/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o +obj-$(CONFIG_GPIO_AAEON) += gpio-aaeon.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_AGGREGATOR) += gpio-aggregator.o --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-aaeon.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-aaeon.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AAEON GPIO driver + * Copyright (c) 2021, AAEON Ltd. + * + * Author: Edward Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "gpio_aaeon" +#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" +#define AAEON_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" + +#define GET_GPIO_NUMBER_ID 0x00010000 +#define GET_LEVEL_METHOD_ID 0x00010001 +#define SET_LEVEL_METHOD_ID 0x00010002 +#define GET_DIRECTION_METHOD_ID 0x00010003 +#define SET_DIRECTION_METHOD_ID 0x00010004 +#define GET_SIO_NUMBER_METHOD_ID 0xF0010 + +struct aaeon_gpio_bank { + struct gpio_chip chip; + unsigned int regbase; + struct aaeon_gpio_data *data; +}; + +struct aaeon_gpio_data { + int nr_bank; + struct aaeon_gpio_bank *bank; +}; + +static int aaeon_gpio_get_number(void); +static int aaeon_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset); +static int aaeon_gpio_output_set_direction(struct gpio_chip *chip, + unsigned int offset, int value); +static int aaeon_gpio_input_set_direction(struct gpio_chip *chip, + unsigned int offset); +static int aaeon_gpio_get(struct gpio_chip *chip, + unsigned int offset); +static void aaeon_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value); + +#define AAEON_GPIO_BANK(_base, _ngpio, _regbase) \ +{ \ + .chip = { \ + .label = DRVNAME, \ + .owner = THIS_MODULE, \ + .get_direction = aaeon_gpio_get_direction, \ + .direction_input = aaeon_gpio_input_set_direction, \ + .direction_output = aaeon_gpio_output_set_direction, \ + .get = aaeon_gpio_get, \ + .set = aaeon_gpio_set, \ + .base = _base, \ + .ngpio = _ngpio, \ + .can_sleep = true, \ + }, \ + .regbase = _regbase, \ +} + +static struct aaeon_gpio_bank aaeon_gpio_bank[] = { + AAEON_GPIO_BANK(0, 0, 0xF0), +}; + +static int aaeon_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + int err, retval; + u32 dev_id = 0x0; + + dev_id |= offset; + err = asus_wmi_evaluate_method(GET_DIRECTION_METHOD_ID, dev_id, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_gpio_input_set_direction(struct gpio_chip *chip, + unsigned int offset) +{ + int err, retval; + u32 dev_id; + + dev_id = BIT(16) | offset; + err = asus_wmi_evaluate_method(SET_DIRECTION_METHOD_ID, dev_id, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_gpio_output_set_direction(struct gpio_chip *chip, + unsigned int offset, int value) +{ + int err, retval; + u32 dev_id = 0x0; + + dev_id |= offset; + err = asus_wmi_evaluate_method(SET_DIRECTION_METHOD_ID, dev_id, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + int err, retval; + u32 dev_id = 0x0; + + dev_id |= offset; + err = asus_wmi_evaluate_method(GET_LEVEL_METHOD_ID, dev_id, 0, &retval); + if (err) + return err; + + return retval; +} + +static void aaeon_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + int retval; + u32 dev_id = offset; + + if (value) + dev_id = BIT(16) | dev_id; + + asus_wmi_evaluate_method(SET_LEVEL_METHOD_ID, dev_id, 0, &retval); +} + +static int aaeon_gpio_get_number(void) +{ + int err, retval; + + err = asus_wmi_evaluate_method(GET_GPIO_NUMBER_ID, + GET_SIO_NUMBER_METHOD_ID, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int __init aaeon_gpio_probe(struct platform_device *pdev) +{ + int err, i; + int dio_number = 0; + struct aaeon_gpio_data *data; + struct aaeon_gpio_bank *bank; + + /* Prevent other drivers adding this platfom device */ + if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) { + pr_debug("AAEON Management GUID not found\n"); + return -ENODEV; + } + + dio_number = aaeon_gpio_get_number(); + if (dio_number < 0) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->nr_bank = ARRAY_SIZE(aaeon_gpio_bank); + data->bank = aaeon_gpio_bank; + platform_set_drvdata(pdev, data); + bank = &data->bank[0]; + bank->chip.parent = &pdev->dev; + bank->chip.ngpio = dio_number; + bank->data = data; + err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank); + if (err) + pr_debug("Failed to register gpiochip %d: %d\n", i, err); + + return err; +} + +static struct platform_driver aaeon_gpio_driver = { + .driver = { + .name = "gpio-aaeon", + }, +}; + +module_platform_driver_probe(aaeon_gpio_driver, aaeon_gpio_probe); + +MODULE_ALIAS("platform:gpio-aaeon"); +MODULE_DESCRIPTION("AAEON GPIO Driver"); +MODULE_AUTHOR("Edward Lin "); +MODULE_LICENSE("GPL v2"); --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-crystalcove.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-crystalcove.c @@ -92,7 +92,7 @@ case 0x5e: return GPIOPANELCTL; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } } --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-davinci.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-davinci.c @@ -225,6 +225,11 @@ else nirq = DIV_ROUND_UP(ngpio, 16); + if (nirq > MAX_INT_PER_BANK) { + dev_err(dev, "Too many IRQs!\n"); + return -EINVAL; + } + chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL); if (!chips) return -ENOMEM; --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-lpc32xx.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-lpc32xx.c @@ -529,6 +529,7 @@ { .compatible = "nxp,lpc3220-gpio", }, { }, }; +MODULE_DEVICE_TABLE(of, lpc32xx_gpio_of_match); static struct platform_driver lpc32xx_gpio_driver = { .driver = { --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-mmio.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-mmio.c @@ -619,8 +619,6 @@ ret = gpiochip_get_ngpios(gc, dev); if (ret) gc->ngpio = gc->bgpio_bits; - else - gc->bgpio_bits = roundup_pow_of_two(round_up(gc->ngpio, 8)); ret = bgpio_setup_io(gc, dat, set, clr, flags); if (ret) --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-npcm-sgpio.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-npcm-sgpio.c @@ -434,7 +434,7 @@ struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct irq_chip *ic = irq_desc_get_chip(desc); struct npcm_sgpio *gpio = gpiochip_get_data(gc); - unsigned int i, j, girq; + unsigned int i, j; unsigned long reg; chained_irq_enter(ic, desc); @@ -443,11 +443,9 @@ const struct npcm_sgpio_bank *bank = &npcm_sgpio_banks[i]; reg = ioread8(bank_reg(gpio, bank, EVENT_STS)); - for_each_set_bit(j, ®, 8) { - girq = irq_find_mapping(gc->irq.domain, - i * 8 + gpio->nout_sgpio + j); - generic_handle_domain_irq(gc->irq.domain, girq); - } + for_each_set_bit(j, ®, 8) + generic_handle_domain_irq(gc->irq.domain, + i * 8 + gpio->nout_sgpio + j); } chained_irq_exit(ic, desc); --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-pca953x.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-pca953x.c @@ -758,6 +758,8 @@ int level; if (chip->driver_data & PCA_PCAL) { + guard(mutex)(&chip->i2c_lock); + /* Enable latch on interrupt-enabled inputs */ pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask); --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-tangier.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-tangier.c @@ -195,7 +195,8 @@ static void tng_irq_ack(struct irq_data *d) { - struct tng_gpio *priv = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tng_gpio *priv = gpiochip_get_data(gc); irq_hw_number_t gpio = irqd_to_hwirq(d); void __iomem *gisr; u8 shift; @@ -227,7 +228,8 @@ static void tng_irq_mask(struct irq_data *d) { - struct tng_gpio *priv = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tng_gpio *priv = gpiochip_get_data(gc); irq_hw_number_t gpio = irqd_to_hwirq(d); tng_irq_unmask_mask(priv, gpio, false); @@ -236,7 +238,8 @@ static void tng_irq_unmask(struct irq_data *d) { - struct tng_gpio *priv = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tng_gpio *priv = gpiochip_get_data(gc); irq_hw_number_t gpio = irqd_to_hwirq(d); gpiochip_enable_irq(&priv->chip, gpio); --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-tegra186.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-tegra186.c @@ -36,12 +36,6 @@ #define TEGRA186_GPIO_SCR_SEC_REN BIT(27) #define TEGRA186_GPIO_SCR_SEC_G1W BIT(9) #define TEGRA186_GPIO_SCR_SEC_G1R BIT(1) -#define TEGRA186_GPIO_FULL_ACCESS (TEGRA186_GPIO_SCR_SEC_WEN | \ - TEGRA186_GPIO_SCR_SEC_REN | \ - TEGRA186_GPIO_SCR_SEC_G1R | \ - TEGRA186_GPIO_SCR_SEC_G1W) -#define TEGRA186_GPIO_SCR_SEC_ENABLE (TEGRA186_GPIO_SCR_SEC_WEN | \ - TEGRA186_GPIO_SCR_SEC_REN) /* control registers */ #define TEGRA186_GPIO_ENABLE_CONFIG 0x00 @@ -177,10 +171,18 @@ value = __raw_readl(secure + TEGRA186_GPIO_SCR); - if ((value & TEGRA186_GPIO_SCR_SEC_ENABLE) == 0) - return true; - - if ((value & TEGRA186_GPIO_FULL_ACCESS) == TEGRA186_GPIO_FULL_ACCESS) + /* + * When SCR_SEC_[R|W]EN is unset, then we have full read/write access to all the + * registers for given GPIO pin. + * When SCR_SEC[R|W]EN is set, then there is need to further check the accompanying + * SCR_SEC_G1[R|W] bit to determine read/write access to all the registers for given + * GPIO pin. + */ + + if (((value & TEGRA186_GPIO_SCR_SEC_REN) == 0 || + ((value & TEGRA186_GPIO_SCR_SEC_REN) && (value & TEGRA186_GPIO_SCR_SEC_G1R))) && + ((value & TEGRA186_GPIO_SCR_SEC_WEN) == 0 || + ((value & TEGRA186_GPIO_SCR_SEC_WEN) && (value & TEGRA186_GPIO_SCR_SEC_G1W)))) return true; return false; --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-tqmx86.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-tqmx86.c @@ -6,6 +6,7 @@ * Vadim V.Vlasov */ +#include #include #include #include @@ -28,16 +29,25 @@ #define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */ #define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */ +#define TQMX86_GPII_NONE 0 #define TQMX86_GPII_FALLING BIT(0) #define TQMX86_GPII_RISING BIT(1) +/* Stored in irq_type as a trigger type, but not actually valid as a register + * value, so the name doesn't use "GPII" + */ +#define TQMX86_INT_BOTH (BIT(0) | BIT(1)) #define TQMX86_GPII_MASK (BIT(0) | BIT(1)) #define TQMX86_GPII_BITS 2 +/* Stored in irq_type with GPII bits */ +#define TQMX86_INT_UNMASKED BIT(2) struct tqmx86_gpio_data { struct gpio_chip chip; void __iomem *io_base; int irq; + /* Lock must be held for accessing output and irq_type fields */ raw_spinlock_t spinlock; + DECLARE_BITMAP(output, TQMX86_NGPIO); u8 irq_type[TQMX86_NGPI]; }; @@ -64,15 +74,10 @@ { struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); unsigned long flags; - u8 val; raw_spin_lock_irqsave(&gpio->spinlock, flags); - val = tqmx86_gpio_read(gpio, TQMX86_GPIOD); - if (value) - val |= BIT(offset); - else - val &= ~BIT(offset); - tqmx86_gpio_write(gpio, val, TQMX86_GPIOD); + __assign_bit(offset, gpio->output, value); + tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); raw_spin_unlock_irqrestore(&gpio->spinlock, flags); } @@ -107,21 +112,38 @@ return GPIO_LINE_DIRECTION_OUT; } +static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset) + __must_hold(&gpio->spinlock) +{ + u8 type = TQMX86_GPII_NONE, gpiic; + + if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) { + type = gpio->irq_type[offset] & TQMX86_GPII_MASK; + + if (type == TQMX86_INT_BOTH) + type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO) + ? TQMX86_GPII_FALLING + : TQMX86_GPII_RISING; + } + + gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); + gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS)); + gpiic |= type << (offset * TQMX86_GPII_BITS); + tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); +} + static void tqmx86_gpio_irq_mask(struct irq_data *data) { unsigned int offset = (data->hwirq - TQMX86_NGPO); struct tqmx86_gpio_data *gpio = gpiochip_get_data( irq_data_get_irq_chip_data(data)); unsigned long flags; - u8 gpiic, mask; - - mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS); raw_spin_lock_irqsave(&gpio->spinlock, flags); - gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); - gpiic &= ~mask; - tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); + gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED; + tqmx86_gpio_irq_config(gpio, offset); raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data)); } @@ -131,16 +153,12 @@ struct tqmx86_gpio_data *gpio = gpiochip_get_data( irq_data_get_irq_chip_data(data)); unsigned long flags; - u8 gpiic, mask; - - mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS); gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data)); + raw_spin_lock_irqsave(&gpio->spinlock, flags); - gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); - gpiic &= ~mask; - gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS); - tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); + gpio->irq_type[offset] |= TQMX86_INT_UNMASKED; + tqmx86_gpio_irq_config(gpio, offset); raw_spin_unlock_irqrestore(&gpio->spinlock, flags); } @@ -151,7 +169,7 @@ unsigned int offset = (data->hwirq - TQMX86_NGPO); unsigned int edge_type = type & IRQF_TRIGGER_MASK; unsigned long flags; - u8 new_type, gpiic; + u8 new_type; switch (edge_type) { case IRQ_TYPE_EDGE_RISING: @@ -161,19 +179,16 @@ new_type = TQMX86_GPII_FALLING; break; case IRQ_TYPE_EDGE_BOTH: - new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING; + new_type = TQMX86_INT_BOTH; break; default: return -EINVAL; /* not supported */ } - gpio->irq_type[offset] = new_type; - raw_spin_lock_irqsave(&gpio->spinlock, flags); - gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); - gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS)); - gpiic |= new_type << (offset * TQMX86_GPII_BITS); - tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); + gpio->irq_type[offset] &= ~TQMX86_GPII_MASK; + gpio->irq_type[offset] |= new_type; + tqmx86_gpio_irq_config(gpio, offset); raw_spin_unlock_irqrestore(&gpio->spinlock, flags); return 0; @@ -184,8 +199,8 @@ struct gpio_chip *chip = irq_desc_get_handler_data(desc); struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); struct irq_chip *irq_chip = irq_desc_get_chip(desc); - unsigned long irq_bits; - int i = 0; + unsigned long irq_bits, flags; + int i; u8 irq_status; chained_irq_enter(irq_chip, desc); @@ -194,6 +209,34 @@ tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS); irq_bits = irq_status; + + raw_spin_lock_irqsave(&gpio->spinlock, flags); + for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { + /* + * Edge-both triggers are implemented by flipping the edge + * trigger after each interrupt, as the controller only supports + * either rising or falling edge triggers, but not both. + * + * Internally, the TQMx86 GPIO controller has separate status + * registers for rising and falling edge interrupts. GPIIC + * configures which bits from which register are visible in the + * interrupt status register GPIIS and defines what triggers the + * parent IRQ line. Writing to GPIIS always clears both rising + * and falling interrupt flags internally, regardless of the + * currently configured trigger. + * + * In consequence, we can cleanly implement the edge-both + * trigger in software by first clearing the interrupt and then + * setting the new trigger based on the current GPIO input in + * tqmx86_gpio_irq_config() - even if an edge arrives between + * reading the input and setting the trigger, we will have a new + * interrupt pending. + */ + if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH) + tqmx86_gpio_irq_config(gpio, i); + } + raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + for_each_set_bit(i, &irq_bits, TQMX86_NGPI) generic_handle_domain_irq(gpio->chip.irq.domain, i + TQMX86_NGPO); @@ -277,6 +320,13 @@ tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD); + /* + * Reading the previous output state is not possible with TQMx86 hardware. + * Initialize all outputs to 0 to have a defined state that matches the + * shadow register. + */ + tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD); + chip = &gpio->chip; chip->label = "gpio-tqmx86"; chip->owner = THIS_MODULE; --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-wcove.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-wcove.c @@ -104,7 +104,7 @@ unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE; if (gpio >= WCOVE_GPIO_NUM) - return -EOPNOTSUPP; + return -ENOTSUPP; return reg + gpio; } --- linux-xilinx-6.8.0.orig/drivers/gpio/gpio-zynqmp-modepin.c +++ linux-xilinx-6.8.0/drivers/gpio/gpio-zynqmp-modepin.c @@ -146,6 +146,7 @@ { .compatible = "xlnx,zynqmp-gpio-modepin", }, { } }; +MODULE_DEVICE_TABLE(of, modepin_platform_id); static struct platform_driver modepin_platform_driver = { .driver = { --- linux-xilinx-6.8.0.orig/drivers/gpio/gpiolib-acpi.c +++ linux-xilinx-6.8.0/drivers/gpio/gpiolib-acpi.c @@ -128,7 +128,24 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, void *data) { - return device_match_acpi_handle(&gc->gpiodev->dev, data); + /* First check the actual GPIO device */ + if (device_match_acpi_handle(&gc->gpiodev->dev, data)) + return true; + + /* + * When the ACPI device is artificially split to the banks of GPIOs, + * where each of them is represented by a separate GPIO device, + * the firmware node of the physical device may not be shared among + * the banks as they may require different values for the same property, + * e.g., number of GPIOs in a certain bank. In such case the ACPI handle + * of a GPIO device is NULL and can not be used. Hence we have to check + * the parent device to be sure that there is no match before bailing + * out. + */ + if (gc->parent) + return device_match_acpi_handle(gc->parent, data); + + return false; } /** --- linux-xilinx-6.8.0.orig/drivers/gpio/gpiolib-cdev.c +++ linux-xilinx-6.8.0/drivers/gpio/gpiolib-cdev.c @@ -95,6 +95,10 @@ GPIOHANDLE_REQUEST_OPEN_DRAIN | \ GPIOHANDLE_REQUEST_OPEN_SOURCE) +#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS \ + (GPIOHANDLE_REQUEST_INPUT | \ + GPIOHANDLE_REQUEST_OUTPUT) + static int linehandle_validate_flags(u32 flags) { /* Return an error if an unknown flag is set */ @@ -175,21 +179,21 @@ if (ret) return ret; + /* Lines must be reconfigured explicitly as input or output. */ + if (!(lflags & GPIOHANDLE_REQUEST_DIRECTION_FLAGS)) + return -EINVAL; + for (i = 0; i < lh->num_descs; i++) { desc = lh->descs[i]; - linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags); + linehandle_flags_to_desc_flags(lflags, &desc->flags); - /* - * Lines have to be requested explicitly for input - * or output, else the line will be treated "as is". - */ if (lflags & GPIOHANDLE_REQUEST_OUTPUT) { int val = !!gcnf.default_values[i]; ret = gpiod_direction_output(desc, val); if (ret) return ret; - } else if (lflags & GPIOHANDLE_REQUEST_INPUT) { + } else { ret = gpiod_direction_input(desc); if (ret) return ret; @@ -734,6 +738,25 @@ GPIO_V2_LINE_EVENT_FALLING_EDGE; } +static inline char *make_irq_label(const char *orig) +{ + char *new; + + if (!orig) + return NULL; + + new = kstrdup_and_replace(orig, '/', ':', GFP_KERNEL); + if (!new) + return ERR_PTR(-ENOMEM); + + return new; +} + +static inline void free_irq_label(const char *label) +{ + kfree(label); +} + #ifdef CONFIG_HTE static enum hte_return process_hw_ts_thread(void *p) @@ -1021,6 +1044,7 @@ { unsigned long irqflags; int ret, level, irq; + char *label; /* try hardware */ ret = gpiod_set_debounce(line->desc, debounce_period_us); @@ -1043,11 +1067,17 @@ if (irq < 0) return -ENXIO; + label = make_irq_label(line->req->label); + if (IS_ERR(label)) + return -ENOMEM; + irqflags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; ret = request_irq(irq, debounce_irq_handler, irqflags, - line->req->label, line); - if (ret) + label, line); + if (ret) { + free_irq_label(label); return ret; + } line->irq = irq; } else { ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH); @@ -1092,7 +1122,7 @@ static void edge_detector_stop(struct line *line) { if (line->irq) { - free_irq(line->irq, line); + free_irq_label(free_irq(line->irq, line)); line->irq = 0; } @@ -1116,6 +1146,7 @@ unsigned long irqflags = 0; u64 eflags; int irq, ret; + char *label; eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS; if (eflags && !kfifo_initialized(&line->req->events)) { @@ -1152,11 +1183,17 @@ IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; irqflags |= IRQF_ONESHOT; + label = make_irq_label(line->req->label); + if (IS_ERR(label)) + return PTR_ERR(label); + /* Request a thread to read the events */ ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread, - irqflags, line->req->label, line); - if (ret) + irqflags, label, line); + if (ret) { + free_irq_label(label); return ret; + } line->irq = irq; return 0; @@ -1166,6 +1203,8 @@ struct gpio_v2_line_config *lc, unsigned int line_idx, u64 edflags) { + u64 eflags; + int ret; u64 active_edflags = READ_ONCE(line->edflags); unsigned int debounce_period_us = gpio_v2_line_config_debounce_period(lc, line_idx); @@ -1177,6 +1216,18 @@ /* sw debounced and still will be...*/ if (debounce_period_us && READ_ONCE(line->sw_debounced)) { line_set_debounce_period(line, debounce_period_us); + /* + * ensure event fifo is initialised if edge detection + * is now enabled. + */ + eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS; + if (eflags && !kfifo_initialized(&line->req->events)) { + ret = kfifo_alloc(&line->req->events, + line->req->event_buffer_size, + GFP_KERNEL); + if (ret) + return ret; + } return 0; } @@ -1489,12 +1540,14 @@ line = &lr->lines[i]; desc = lr->lines[i].desc; flags = gpio_v2_line_config_flags(&lc, i); - gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); - edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS; /* - * Lines have to be requested explicitly for input - * or output, else the line will be treated "as is". + * Lines not explicitly reconfigured as input or output + * are left unchanged. */ + if (!(flags & GPIO_V2_LINE_DIRECTION_FLAGS)) + continue; + gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); + edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS; if (flags & GPIO_V2_LINE_FLAG_OUTPUT) { int val = gpio_v2_line_config_output_value(&lc, i); @@ -1502,7 +1555,7 @@ ret = gpiod_direction_output(desc, val); if (ret) return ret; - } else if (flags & GPIO_V2_LINE_FLAG_INPUT) { + } else { ret = gpiod_direction_input(desc); if (ret) return ret; @@ -1979,7 +2032,7 @@ blocking_notifier_chain_unregister(&le->gdev->device_notifier, &le->device_unregistered_nb); if (le->irq) - free_irq(le->irq, le); + free_irq_label(free_irq(le->irq, le)); if (le->desc) gpiod_free(le->desc); kfree(le->label); @@ -2120,6 +2173,7 @@ int fd; int ret; int irq, irqflags = 0; + char *label; if (copy_from_user(&eventreq, ip, sizeof(eventreq))) return -EFAULT; @@ -2204,15 +2258,23 @@ if (ret) goto out_free_le; + label = make_irq_label(le->label); + if (IS_ERR(label)) { + ret = PTR_ERR(label); + goto out_free_le; + } + /* Request a thread to read the events */ ret = request_threaded_irq(irq, lineevent_irq_handler, lineevent_irq_thread, irqflags, - le->label, + label, le); - if (ret) + if (ret) { + free_irq_label(label); goto out_free_le; + } le->irq = irq; @@ -2758,11 +2820,11 @@ struct gpio_chardev_data *cdev = file->private_data; struct gpio_device *gdev = cdev->gdev; - bitmap_free(cdev->watched_lines); blocking_notifier_chain_unregister(&gdev->device_notifier, &cdev->device_unregistered_nb); blocking_notifier_chain_unregister(&gdev->line_state_notifier, &cdev->lineinfo_changed_nb); + bitmap_free(cdev->watched_lines); gpio_device_put(gdev); kfree(cdev); --- linux-xilinx-6.8.0.orig/drivers/gpio/gpiolib-devres.c +++ linux-xilinx-6.8.0/drivers/gpio/gpiolib-devres.c @@ -158,7 +158,7 @@ if (!dr) return ERR_PTR(-ENOMEM); - desc = fwnode_gpiod_get_index(fwnode, con_id, index, flags, label); + desc = gpiod_find_and_request(dev, fwnode, con_id, index, flags, label, false); if (IS_ERR(desc)) { devres_free(dr); return desc; --- linux-xilinx-6.8.0.orig/drivers/gpio/gpiolib-of.c +++ linux-xilinx-6.8.0/drivers/gpio/gpiolib-of.c @@ -202,6 +202,24 @@ */ { "qi,lb60", "rb-gpios", true }, #endif +#if IS_ENABLED(CONFIG_PCI_LANTIQ) + /* + * According to the PCI specification, the RST# pin is an + * active-low signal. However, most of the device trees that + * have been widely used for a long time incorrectly describe + * reset GPIO as active-high, and were also using wrong name + * for the property. + */ + { "lantiq,pci-xway", "gpio-reset", false }, +#endif +#if IS_ENABLED(CONFIG_TOUCHSCREEN_TSC2005) + /* + * DTS for Nokia N900 incorrectly specified "active high" + * polarity for the reset line, while the chip actually + * treats it as "active low". + */ + { "ti,tsc2005", "reset-gpios", false }, +#endif }; unsigned int i; @@ -501,9 +519,9 @@ { "reset", "reset-n-io", "marvell,nfc-uart" }, { "reset", "reset-n-io", "mrvl,nfc-uart" }, #endif -#if !IS_ENABLED(CONFIG_PCI_LANTIQ) +#if IS_ENABLED(CONFIG_PCI_LANTIQ) /* MIPS Lantiq PCI */ - { "reset", "gpios-reset", "lantiq,pci-xway" }, + { "reset", "gpio-reset", "lantiq,pci-xway" }, #endif /* --- linux-xilinx-6.8.0.orig/drivers/gpio/gpiolib.c +++ linux-xilinx-6.8.0/drivers/gpio/gpiolib.c @@ -2402,6 +2402,11 @@ } EXPORT_SYMBOL_GPL(gpiochip_dup_line_label); +static inline const char *function_name_or_default(const char *con_id) +{ + return con_id ?: "(default)"; +} + /** * gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor * @gc: GPIO chip @@ -2430,10 +2435,11 @@ enum gpiod_flags dflags) { struct gpio_desc *desc = gpiochip_get_desc(gc, hwnum); + const char *name = function_name_or_default(label); int ret; if (IS_ERR(desc)) { - chip_err(gc, "failed to get GPIO descriptor\n"); + chip_err(gc, "failed to get GPIO %s descriptor\n", name); return desc; } @@ -2443,8 +2449,8 @@ ret = gpiod_configure_flags(desc, label, lflags, dflags); if (ret) { - chip_err(gc, "setup of own GPIO %s failed\n", label); gpiod_free_commit(desc); + chip_err(gc, "setup of own GPIO %s failed\n", name); return ERR_PTR(ret); } @@ -4119,34 +4125,33 @@ enum gpiod_flags *flags, unsigned long *lookupflags) { + const char *name = function_name_or_default(con_id); struct gpio_desc *desc = ERR_PTR(-ENOENT); if (is_of_node(fwnode)) { - dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n", - fwnode, con_id); + dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n", fwnode, name); desc = of_find_gpio(to_of_node(fwnode), con_id, idx, lookupflags); } else if (is_acpi_node(fwnode)) { - dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n", - fwnode, con_id); + dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n", fwnode, name); desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags); } else if (is_software_node(fwnode)) { - dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n", - fwnode, con_id); + dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n", fwnode, name); desc = swnode_find_gpio(fwnode, con_id, idx, lookupflags); } return desc; } -static struct gpio_desc *gpiod_find_and_request(struct device *consumer, - struct fwnode_handle *fwnode, - const char *con_id, - unsigned int idx, - enum gpiod_flags flags, - const char *label, - bool platform_lookup_allowed) +struct gpio_desc *gpiod_find_and_request(struct device *consumer, + struct fwnode_handle *fwnode, + const char *con_id, + unsigned int idx, + enum gpiod_flags flags, + const char *label, + bool platform_lookup_allowed) { unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT; + const char *name = function_name_or_default(con_id); struct gpio_desc *desc; int ret; @@ -4162,7 +4167,7 @@ } if (IS_ERR(desc)) { - dev_dbg(consumer, "No GPIO consumer %s found\n", con_id); + dev_dbg(consumer, "No GPIO consumer %s found\n", name); return desc; } @@ -4183,15 +4188,14 @@ * * FIXME: Make this more sane and safe. */ - dev_info(consumer, - "nonexclusive access to GPIO for %s\n", con_id); + dev_info(consumer, "nonexclusive access to GPIO for %s\n", name); return desc; } ret = gpiod_configure_flags(desc, con_id, lookupflags, flags); if (ret < 0) { - dev_dbg(consumer, "setup of GPIO %s failed\n", con_id); gpiod_put(desc); + dev_dbg(consumer, "setup of GPIO %s failed\n", name); return ERR_PTR(ret); } @@ -4307,6 +4311,7 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, unsigned long lflags, enum gpiod_flags dflags) { + const char *name = function_name_or_default(con_id); int ret; if (lflags & GPIO_ACTIVE_LOW) @@ -4350,7 +4355,7 @@ /* No particular flag request, return here... */ if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) { - gpiod_dbg(desc, "no flags found for %s\n", con_id); + gpiod_dbg(desc, "no flags found for GPIO %s\n", name); return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpio/gpiolib.h +++ linux-xilinx-6.8.0/drivers/gpio/gpiolib.h @@ -202,6 +202,14 @@ return ret; } +struct gpio_desc *gpiod_find_and_request(struct device *consumer, + struct fwnode_handle *fwnode, + const char *con_id, + unsigned int idx, + enum gpiod_flags flags, + const char *label, + bool platform_lookup_allowed); + int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, unsigned long lflags, enum gpiod_flags dflags); int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -97,7 +97,7 @@ adev->ip_blocks[i].status.hw = false; } - return r; + return 0; } static int --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -198,7 +198,7 @@ extern uint amdgpu_dc_feature_mask; extern uint amdgpu_dc_debug_mask; extern uint amdgpu_dc_visual_confirm; -extern uint amdgpu_dm_abm_level; +extern int amdgpu_dm_abm_level; extern int amdgpu_backlight; extern int amdgpu_damage_clips; extern struct amdgpu_mgpu_info mgpu_info; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -146,7 +146,7 @@ { int ret; - if (!adev->kfd.init_complete) + if (!adev->kfd.init_complete || adev->kfd.client.dev) return 0; ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd", @@ -455,6 +455,9 @@ else mem_info->local_mem_size_private = KFD_XCP_MEMORY_SIZE(adev, xcp->id); + } else if (adev->flags & AMD_IS_APU) { + mem_info->local_mem_size_public = (ttm_tt_pages_limit() << PAGE_SHIFT); + mem_info->local_mem_size_private = 0; } else { mem_info->local_mem_size_public = adev->gmc.visible_vram_size; mem_info->local_mem_size_private = adev->gmc.real_vram_size - @@ -803,6 +806,8 @@ } do_div(tmp, adev->xcp_mgr->num_xcp_per_mem_partition); return ALIGN_DOWN(tmp, PAGE_SIZE); + } else if (adev->flags & AMD_IS_APU) { + return (ttm_tt_pages_limit() << PAGE_SHIFT); } else { return adev->gmc.real_vram_size; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -196,7 +196,7 @@ return -EINVAL; vram_size = KFD_XCP_MEMORY_SIZE(adev, xcp_id); - if (adev->gmc.is_app_apu) { + if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) { system_mem_needed = size; ttm_mem_needed = size; } @@ -220,7 +220,7 @@ (kfd_mem_limit.ttm_mem_used + ttm_mem_needed > kfd_mem_limit.max_ttm_mem_limit) || (adev && xcp_id >= 0 && adev->kfd.vram_used[xcp_id] + vram_needed > - vram_size - reserved_for_pt)) { + vram_size - reserved_for_pt - atomic64_read(&adev->vram_pin_size))) { ret = -ENOMEM; goto release; } @@ -232,7 +232,8 @@ "adev reference can't be null when vram is used"); if (adev && xcp_id >= 0) { adev->kfd.vram_used[xcp_id] += vram_needed; - adev->kfd.vram_used_aligned[xcp_id] += adev->gmc.is_app_apu ? + adev->kfd.vram_used_aligned[xcp_id] += + (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) ? vram_needed : ALIGN(vram_needed, VRAM_AVAILABLITY_ALIGN); } @@ -260,7 +261,7 @@ if (adev) { adev->kfd.vram_used[xcp_id] -= size; - if (adev->gmc.is_app_apu) { + if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) { adev->kfd.vram_used_aligned[xcp_id] -= size; kfd_mem_limit.system_mem_used -= size; kfd_mem_limit.ttm_mem_used -= size; @@ -887,7 +888,7 @@ * if peer device has large BAR. In contrast, access over xGMI is * allowed for both small and large BAR configurations of peer device */ - if ((adev != bo_adev && !adev->gmc.is_app_apu) && + if ((adev != bo_adev && !(adev->gmc.is_app_apu || adev->flags & AMD_IS_APU)) && ((mem->domain == AMDGPU_GEM_DOMAIN_VRAM) || (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) || (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP))) { @@ -1186,7 +1187,8 @@ int ret; ctx->sync = &mem->sync; - drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); + drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT | + DRM_EXEC_IGNORE_DUPLICATES, 0); drm_exec_until_all_locked(&ctx->exec) { ctx->n_vms = 0; list_for_each_entry(entry, &mem->attachments, list) { @@ -1653,7 +1655,7 @@ - atomic64_read(&adev->vram_pin_size) - reserved_for_pt; - if (adev->gmc.is_app_apu) { + if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) { system_mem_available = no_system_mem_limit ? kfd_mem_limit.max_system_mem_limit : kfd_mem_limit.max_system_mem_limit - @@ -1701,7 +1703,7 @@ if (flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) { domain = alloc_domain = AMDGPU_GEM_DOMAIN_VRAM; - if (adev->gmc.is_app_apu) { + if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) { domain = AMDGPU_GEM_DOMAIN_GTT; alloc_domain = AMDGPU_GEM_DOMAIN_GTT; alloc_flags = 0; @@ -1851,6 +1853,7 @@ err_bo_create: amdgpu_amdkfd_unreserve_mem_limit(adev, aligned_size, flags, xcp_id); err_reserve_limit: + amdgpu_sync_free(&(*mem)->sync); mutex_destroy(&(*mem)->lock); if (gobj) drm_gem_object_put(gobj); @@ -1947,7 +1950,7 @@ if (size) { if (!is_imported && (mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_VRAM || - (adev->gmc.is_app_apu && + ((adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) && mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_GTT))) *size = bo_size; else @@ -2370,8 +2373,9 @@ (*mem)->dmabuf = dma_buf; (*mem)->bo = bo; (*mem)->va = va; - (*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) && !adev->gmc.is_app_apu ? - AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT; + (*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) && + !(adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) ? + AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT; (*mem)->mapped_to_gpu_memory = 0; (*mem)->process_info = avm->process_info; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -211,6 +211,7 @@ struct atom_integrated_system_info_v1_11 v11; struct atom_integrated_system_info_v1_12 v12; struct atom_integrated_system_info_v2_1 v21; + struct atom_integrated_system_info_v2_3 v23; }; union umc_info { @@ -359,6 +360,20 @@ if (vram_type) *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); break; + case 3: + mem_channel_number = igp_info->v23.umachannelnumber; + if (!mem_channel_number) + mem_channel_number = 1; + mem_type = igp_info->v23.memorytype; + if (mem_type == LpDdr5MemType) + mem_channel_width = 32; + else + mem_channel_width = 64; + if (vram_width) + *vram_width = mem_channel_number * mem_channel_width; + if (vram_type) + *vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type); + break; default: return -EINVAL; } @@ -384,7 +399,7 @@ mem_channel_number = vram_info->v30.channel_num; mem_channel_width = vram_info->v30.channel_width; if (vram_width) - *vram_width = mem_channel_number * (1 << mem_channel_width); + *vram_width = mem_channel_number * 16; break; default: return -EINVAL; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -819,7 +819,7 @@ p->bytes_moved += ctx.bytes_moved; if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && - amdgpu_bo_in_cpu_visible_vram(bo)) + amdgpu_res_cpu_visible(adev, bo->tbo.resource)) p->bytes_moved_vis += ctx.bytes_moved; if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -2060,12 +2060,13 @@ struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private; char reg_offset[11]; uint32_t *new = NULL, *tmp = NULL; - int ret, i = 0, len = 0; + unsigned int len = 0; + int ret, i = 0; do { memset(reg_offset, 0, 11); if (copy_from_user(reg_offset, buf + len, - min(10, ((int)size-len)))) { + min(10, (size-len)))) { ret = -EFAULT; goto error_free; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4120,18 +4120,22 @@ adev->ip_blocks[i].status.hw = true; } } + } else if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && + !amdgpu_device_has_display_hardware(adev)) { + r = psp_gpu_reset(adev); } else { - tmp = amdgpu_reset_method; - /* It should do a default reset when loading or reloading the driver, - * regardless of the module parameter reset_method. - */ - amdgpu_reset_method = AMD_RESET_METHOD_NONE; - r = amdgpu_asic_reset(adev); - amdgpu_reset_method = tmp; - if (r) { - dev_err(adev->dev, "asic reset on init failed\n"); - goto failed; - } + tmp = amdgpu_reset_method; + /* It should do a default reset when loading or reloading the driver, + * regardless of the module parameter reset_method. + */ + amdgpu_reset_method = AMD_RESET_METHOD_NONE; + r = amdgpu_asic_reset(adev); + amdgpu_reset_method = tmp; + } + + if (r) { + dev_err(adev->dev, "asic reset on init failed\n"); + goto failed; } } @@ -4524,6 +4528,8 @@ if (r) goto unprepare; + flush_delayed_work(&adev->gfx.gfx_off_delay_work); + for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.valid) continue; @@ -5100,11 +5106,14 @@ dev_info(adev->dev, "GPU mode1 reset\n"); + /* Cache the state before bus master disable. The saved config space + * values are used in other cases like restore after mode-2 reset. + */ + amdgpu_device_cache_pci_state(adev->pdev); + /* disable BM */ pci_clear_master(adev->pdev); - amdgpu_device_cache_pci_state(adev->pdev); - if (amdgpu_dpm_is_mode1_reset_supported(adev)) { dev_info(adev->dev, "GPU smu mode1 reset\n"); ret = amdgpu_dpm_mode1_reset(adev); @@ -5786,13 +5795,18 @@ *speed = PCI_SPEED_UNKNOWN; *width = PCIE_LNK_WIDTH_UNKNOWN; - while ((parent = pci_upstream_bridge(parent))) { - /* skip upstream/downstream switches internal to dGPU*/ - if (parent->vendor == PCI_VENDOR_ID_ATI) - continue; - *speed = pcie_get_speed_cap(parent); - *width = pcie_get_width_cap(parent); - break; + if (amdgpu_device_pcie_dynamic_switching_supported(adev)) { + while ((parent = pci_upstream_bridge(parent))) { + /* skip upstream/downstream switches internal to dGPU*/ + if (parent->vendor == PCI_VENDOR_ID_ATI) + continue; + *speed = pcie_get_speed_cap(parent); + *width = pcie_get_width_cap(parent); + break; + } + } else { + /* use the current speeds rather than max if switching is not supported */ + pcie_bandwidth_available(adev->pdev, NULL, speed, width); } } @@ -6107,6 +6121,20 @@ struct amdgpu_reset_context reset_context; u32 memsize; struct list_head device_list; + struct amdgpu_hive_info *hive; + int hive_ras_recovery = 0; + struct amdgpu_ras *ras; + + /* PCI error slot reset should be skipped During RAS recovery */ + hive = amdgpu_get_xgmi_hive(adev); + if (hive) { + hive_ras_recovery = atomic_read(&hive->ras_recovery); + amdgpu_put_xgmi_hive(hive); + } + ras = amdgpu_ras_get_context(adev); + if ((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3)) && + ras && (atomic_read(&ras->in_recovery) || hive_ras_recovery)) + return PCI_ERS_RESULT_RECOVERED; DRM_INFO("PCI error: slot reset callback!!\n"); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -1278,11 +1278,10 @@ * 0b10 : encode is disabled * 0b01 : decode is disabled */ - adev->vcn.vcn_config[adev->vcn.num_vcn_inst] = - ip->revision & 0xc0; - ip->revision &= ~0xc0; if (adev->vcn.num_vcn_inst < AMDGPU_MAX_VCN_INSTANCES) { + adev->vcn.vcn_config[adev->vcn.num_vcn_inst] = + ip->revision & 0xc0; adev->vcn.num_vcn_inst++; adev->vcn.inst_mask |= (1U << ip->instance_number); @@ -1293,6 +1292,7 @@ adev->vcn.num_vcn_inst + 1, AMDGPU_MAX_VCN_INSTANCES); } + ip->revision &= ~0xc0; } if (le16_to_cpu(ip->hw_id) == SDMA0_HWID || le16_to_cpu(ip->hw_id) == SDMA1_HWID || @@ -1867,6 +1867,7 @@ amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block); break; case IP_VERSION(14, 0, 0): + case IP_VERSION(14, 0, 1): amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block); break; default: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -849,12 +849,13 @@ * the ABM algorithm, with 1 being the least reduction and 4 being the most * reduction. * - * Defaults to 0, or disabled. Userspace can still override this level later - * after boot. + * Defaults to -1, or disabled. Userspace can only override this level after + * boot if it's set to auto. */ -uint amdgpu_dm_abm_level; -MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); -module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); +int amdgpu_dm_abm_level = -1; +MODULE_PARM_DESC(abmlevel, + "ABM level (0 = off, 1-4 = backlight reduction level, -1 auto (default))"); +module_param_named(abmlevel, amdgpu_dm_abm_level, int, 0444); int amdgpu_backlight = -1; MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))"); @@ -2451,8 +2452,11 @@ } for (i = 0; i < mgpu_info.num_dgpu; i++) { adev = mgpu_info.gpu_ins[i].adev; - if (!adev->kfd.init_complete) + if (!adev->kfd.init_complete) { + kgd2kfd_init_zone_device(adev); amdgpu_amdkfd_device_init(adev); + amdgpu_amdkfd_drm_client_create(adev); + } amdgpu_ttm_set_buffer_funcs_status(adev, true); } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c @@ -97,6 +97,10 @@ stats.requested_visible_vram/1024UL); drm_printf(p, "amd-requested-gtt:\t%llu KiB\n", stats.requested_gtt/1024UL); + drm_printf(p, "drm-shared-vram:\t%llu KiB\n", stats.vram_shared/1024UL); + drm_printf(p, "drm-shared-gtt:\t%llu KiB\n", stats.gtt_shared/1024UL); + drm_printf(p, "drm-shared-cpu:\t%llu KiB\n", stats.cpu_shared/1024UL); + for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) { if (!usage[hw_ip]) continue; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -1205,7 +1205,8 @@ fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes); break; default: - break; + dev_err(adev->dev, "Invalid ucode id %u\n", ucode_id); + return; } if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -684,12 +684,17 @@ struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; unsigned int ndw; - signed long r; + int r; uint32_t seq; - if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready || - !down_read_trylock(&adev->reset_domain->sem)) { + /* + * A GPU reset should flush all TLBs anyway, so no need to do + * this while one is ongoing. + */ + if (!down_read_trylock(&adev->reset_domain->sem)) + return 0; + if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) { if (adev->gmc.flush_tlb_needs_extra_type_2) adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, 2, all_hub, @@ -703,43 +708,40 @@ adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub, inst); - return 0; - } + r = 0; + } else { + /* 2 dwords flush + 8 dwords fence */ + ndw = kiq->pmf->invalidate_tlbs_size + 8; - /* 2 dwords flush + 8 dwords fence */ - ndw = kiq->pmf->invalidate_tlbs_size + 8; + if (adev->gmc.flush_tlb_needs_extra_type_2) + ndw += kiq->pmf->invalidate_tlbs_size; - if (adev->gmc.flush_tlb_needs_extra_type_2) - ndw += kiq->pmf->invalidate_tlbs_size; + if (adev->gmc.flush_tlb_needs_extra_type_0) + ndw += kiq->pmf->invalidate_tlbs_size; - if (adev->gmc.flush_tlb_needs_extra_type_0) - ndw += kiq->pmf->invalidate_tlbs_size; + spin_lock(&adev->gfx.kiq[inst].ring_lock); + amdgpu_ring_alloc(ring, ndw); + if (adev->gmc.flush_tlb_needs_extra_type_2) + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); - spin_lock(&adev->gfx.kiq[inst].ring_lock); - amdgpu_ring_alloc(ring, ndw); - if (adev->gmc.flush_tlb_needs_extra_type_2) - kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub); - - if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0) - kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub); - - kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); - r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); - if (r) { - amdgpu_ring_undo(ring); - spin_unlock(&adev->gfx.kiq[inst].ring_lock); - goto error_unlock_reset; - } + if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0) + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub); - amdgpu_ring_commit(ring); - spin_unlock(&adev->gfx.kiq[inst].ring_lock); - r = amdgpu_fence_wait_polling(ring, seq, usec_timeout); - if (r < 1) { - dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r); - r = -ETIME; - goto error_unlock_reset; + kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub); + r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT); + if (r) { + amdgpu_ring_undo(ring); + spin_unlock(&adev->gfx.kiq[inst].ring_lock); + goto error_unlock_reset; + } + + amdgpu_ring_commit(ring); + spin_unlock(&adev->gfx.kiq[inst].ring_lock); + if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) { + dev_err(adev->dev, "timeout waiting for kiq fence\n"); + r = -ETIME; + } } - r = 0; error_unlock_reset: up_read(&adev->reset_domain->sem); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c @@ -129,13 +129,25 @@ */ int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr) { + int r; + if (bo->kfd_bo) - return mmu_interval_notifier_insert(&bo->notifier, current->mm, + r = mmu_interval_notifier_insert(&bo->notifier, current->mm, addr, amdgpu_bo_size(bo), &amdgpu_hmm_hsa_ops); - return mmu_interval_notifier_insert(&bo->notifier, current->mm, addr, - amdgpu_bo_size(bo), - &amdgpu_hmm_gfx_ops); + else + r = mmu_interval_notifier_insert(&bo->notifier, current->mm, addr, + amdgpu_bo_size(bo), + &amdgpu_hmm_gfx_ops); + if (r) + /* + * Make sure amdgpu_hmm_unregister() doesn't call + * mmu_interval_notifier_remove() when the notifier isn't properly + * initialized. + */ + bo->notifier.mm = NULL; + + return r; } /** --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -445,6 +445,14 @@ entry.ih = ih; entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; + + /* + * timestamp is not supported on some legacy SOCs (cik, cz, iceland, + * si and tonga), so initialize timestamp and timestamp_src to 0 + */ + entry.timestamp = 0; + entry.timestamp_src = 0; + amdgpu_ih_decode_iv(adev, &entry); trace_amdgpu_iv(ih - &adev->irq.ih, &entry); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -300,12 +300,15 @@ dma_fence_set_error(finished, -ECANCELED); if (finished->error < 0) { - DRM_INFO("Skip scheduling IBs!\n"); + dev_dbg(adev->dev, "Skip scheduling IBs in ring(%s)", + ring->name); } else { r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job, &fence); if (r) - DRM_ERROR("Error scheduling IBs (%d)\n", r); + dev_err(adev->dev, + "Error scheduling IBs (%d) in ring(%s)", r, + ring->name); } job->job_run_counter++; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -1129,6 +1129,7 @@ return; amdgpu_mes_remove_hw_queue(adev, ring->hw_queue_id); + del_timer_sync(&ring->fence_drv.fallback_timer); amdgpu_ring_fini(ring); kfree(ring); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -608,6 +608,8 @@ else amdgpu_bo_placement_from_domain(bo, bp->domain); if (bp->type == ttm_bo_type_kernel) + bo->tbo.priority = 2; + else if (!(bp->flags & AMDGPU_GEM_CREATE_DISCARDABLE)) bo->tbo.priority = 1; if (!bp->destroy) @@ -620,8 +622,7 @@ return r; if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && - bo->tbo.resource->mem_type == TTM_PL_VRAM && - amdgpu_bo_in_cpu_visible_vram(bo)) + amdgpu_res_cpu_visible(adev, bo->tbo.resource)) amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, ctx.bytes_moved); else @@ -1245,14 +1246,18 @@ * amdgpu_bo_move_notify - notification about a memory move * @bo: pointer to a buffer object * @evict: if this move is evicting the buffer from the graphics address space + * @new_mem: new resource for backing the BO * * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs * bookkeeping. * TTM driver callback which is called when ttm moves a buffer. */ -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict) +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, + bool evict, + struct ttm_resource *new_mem) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); + struct ttm_resource *old_mem = bo->resource; struct amdgpu_bo *abo; if (!amdgpu_bo_is_amdgpu_bo(bo)) @@ -1264,37 +1269,50 @@ amdgpu_bo_kunmap(abo); if (abo->tbo.base.dma_buf && !abo->tbo.base.import_attach && - bo->resource->mem_type != TTM_PL_SYSTEM) + old_mem && old_mem->mem_type != TTM_PL_SYSTEM) dma_buf_move_notify(abo->tbo.base.dma_buf); - /* remember the eviction */ - if (evict) - atomic64_inc(&adev->num_evictions); + /* move_notify is called before move happens */ + trace_amdgpu_bo_move(abo, new_mem ? new_mem->mem_type : -1, + old_mem ? old_mem->mem_type : -1); } void amdgpu_bo_get_memory(struct amdgpu_bo *bo, struct amdgpu_mem_stats *stats) { + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + struct ttm_resource *res = bo->tbo.resource; uint64_t size = amdgpu_bo_size(bo); + struct drm_gem_object *obj; unsigned int domain; + bool shared; /* Abort if the BO doesn't currently have a backing store */ - if (!bo->tbo.resource) + if (!res) return; - domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type); + obj = &bo->tbo.base; + shared = drm_gem_object_is_shared_for_memory_stats(obj); + + domain = amdgpu_mem_type_to_domain(res->mem_type); switch (domain) { case AMDGPU_GEM_DOMAIN_VRAM: stats->vram += size; - if (amdgpu_bo_in_cpu_visible_vram(bo)) + if (amdgpu_res_cpu_visible(adev, bo->tbo.resource)) stats->visible_vram += size; + if (shared) + stats->vram_shared += size; break; case AMDGPU_GEM_DOMAIN_GTT: stats->gtt += size; + if (shared) + stats->gtt_shared += size; break; case AMDGPU_GEM_DOMAIN_CPU: default: stats->cpu += size; + if (shared) + stats->cpu_shared += size; break; } @@ -1381,10 +1399,7 @@ /* Remember that this BO was accessed by the CPU */ abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; - if (bo->resource->mem_type != TTM_PL_VRAM) - return 0; - - if (amdgpu_bo_in_cpu_visible_vram(abo)) + if (amdgpu_res_cpu_visible(adev, bo->resource)) return 0; /* Can't move a pinned BO to visible VRAM */ @@ -1408,7 +1423,7 @@ /* this should never happen */ if (bo->resource->mem_type == TTM_PL_VRAM && - !amdgpu_bo_in_cpu_visible_vram(abo)) + !amdgpu_res_cpu_visible(adev, bo->resource)) return VM_FAULT_SIGBUS; ttm_bo_move_to_lru_tail_unlocked(bo); @@ -1572,6 +1587,7 @@ */ u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m) { + struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); struct dma_buf_attachment *attachment; struct dma_buf *dma_buf; const char *placement; @@ -1580,10 +1596,11 @@ if (dma_resv_trylock(bo->tbo.base.resv)) { unsigned int domain; + domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type); switch (domain) { case AMDGPU_GEM_DOMAIN_VRAM: - if (amdgpu_bo_in_cpu_visible_vram(bo)) + if (amdgpu_res_cpu_visible(adev, bo->tbo.resource)) placement = "VRAM VISIBLE"; else placement = "VRAM"; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -138,12 +138,18 @@ struct amdgpu_mem_stats { /* current VRAM usage, includes visible VRAM */ uint64_t vram; + /* current shared VRAM usage, includes visible VRAM */ + uint64_t vram_shared; /* current visible VRAM usage */ uint64_t visible_vram; /* current GTT usage */ uint64_t gtt; + /* current shared GTT usage */ + uint64_t gtt_shared; /* current system memory usage */ uint64_t cpu; + /* current shared system memory usage */ + uint64_t cpu_shared; /* sum of evicted buffers, includes visible VRAM */ uint64_t evicted_vram; /* sum of evicted buffers due to CPU access */ @@ -245,28 +251,6 @@ } /** - * amdgpu_bo_in_cpu_visible_vram - check if BO is (partly) in visible VRAM - */ -static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo) -{ - struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); - struct amdgpu_res_cursor cursor; - - if (!bo->tbo.resource || bo->tbo.resource->mem_type != TTM_PL_VRAM) - return false; - - amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor); - while (cursor.remaining) { - if (cursor.start < adev->gmc.visible_vram_size) - return true; - - amdgpu_res_next(&cursor, cursor.size); - } - - return false; -} - -/** * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced */ static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo) @@ -344,7 +328,9 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, size_t buffer_size, uint32_t *metadata_size, uint64_t *flags); -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict); +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, + bool evict, + struct ttm_resource *new_mem); void amdgpu_bo_release_notify(struct ttm_buffer_object *bo); vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -38,6 +38,7 @@ */ #define AMDGPU_RAS_INST_MASK 0xfffff000 #define AMDGPU_RAS_INST_SHIFT 0xc +#define AMDGPU_RAS_GPU_ERR_HBM_ID(x) AMDGPU_GET_REG_FIELD(x, 14, 13) enum amdgpu_ras_block { AMDGPU_RAS_BLOCK__UMC = 0, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -524,46 +524,58 @@ { struct amdgpu_ring *ring = file_inode(f)->i_private; volatile u32 *mqd; - int r; + u32 *kbuf; + int r, i; uint32_t value, result; if (*pos & 3 || size & 3) return -EINVAL; - result = 0; + kbuf = kmalloc(ring->mqd_size, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; r = amdgpu_bo_reserve(ring->mqd_obj, false); if (unlikely(r != 0)) - return r; + goto err_free; r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&mqd); - if (r) { - amdgpu_bo_unreserve(ring->mqd_obj); - return r; - } + if (r) + goto err_unreserve; + + /* + * Copy to local buffer to avoid put_user(), which might fault + * and acquire mmap_sem, under reservation_ww_class_mutex. + */ + for (i = 0; i < ring->mqd_size/sizeof(u32); i++) + kbuf[i] = mqd[i]; + + amdgpu_bo_kunmap(ring->mqd_obj); + amdgpu_bo_unreserve(ring->mqd_obj); + result = 0; while (size) { if (*pos >= ring->mqd_size) - goto done; + break; - value = mqd[*pos/4]; + value = kbuf[*pos/4]; r = put_user(value, (uint32_t *)buf); if (r) - goto done; + goto err_free; buf += 4; result += 4; size -= 4; *pos += 4; } -done: - amdgpu_bo_kunmap(ring->mqd_obj); - mqd = NULL; - amdgpu_bo_unreserve(ring->mqd_obj); - if (r) - return r; - + kfree(kbuf); return result; + +err_unreserve: + amdgpu_bo_unreserve(ring->mqd_obj); +err_free: + kfree(kbuf); + return r; } static const struct file_operations amdgpu_debugfs_mqd_fops = { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -137,7 +137,7 @@ amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU); } else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) && !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && - amdgpu_bo_in_cpu_visible_vram(abo)) { + amdgpu_res_cpu_visible(adev, bo->resource)) { /* Try evicting to the CPU inaccessible part of VRAM * first, but only set GTT as busy placement, so this @@ -408,40 +408,55 @@ return r; } -/* - * amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy +/** + * amdgpu_res_cpu_visible - Check that resource can be accessed by CPU + * @adev: amdgpu device + * @res: the resource to check * - * Called by amdgpu_bo_move() + * Returns: true if the full resource is CPU visible, false otherwise. */ -static bool amdgpu_mem_visible(struct amdgpu_device *adev, - struct ttm_resource *mem) +bool amdgpu_res_cpu_visible(struct amdgpu_device *adev, + struct ttm_resource *res) { - u64 mem_size = (u64)mem->size; struct amdgpu_res_cursor cursor; - u64 end; - if (mem->mem_type == TTM_PL_SYSTEM || - mem->mem_type == TTM_PL_TT) + if (!res) + return false; + + if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT || + res->mem_type == AMDGPU_PL_PREEMPT || res->mem_type == AMDGPU_PL_DOORBELL) return true; - if (mem->mem_type != TTM_PL_VRAM) + + if (res->mem_type != TTM_PL_VRAM) return false; - amdgpu_res_first(mem, 0, mem_size, &cursor); - end = cursor.start + cursor.size; + amdgpu_res_first(res, 0, res->size, &cursor); while (cursor.remaining) { + if ((cursor.start + cursor.size) > adev->gmc.visible_vram_size) + return false; amdgpu_res_next(&cursor, cursor.size); + } - if (!cursor.remaining) - break; + return true; +} - /* ttm_resource_ioremap only supports contiguous memory */ - if (end != cursor.start) - return false; +/* + * amdgpu_res_copyable - Check that memory can be accessed by ttm_bo_move_memcpy + * + * Called by amdgpu_bo_move() + */ +static bool amdgpu_res_copyable(struct amdgpu_device *adev, + struct ttm_resource *mem) +{ + if (!amdgpu_res_cpu_visible(adev, mem)) + return false; - end = cursor.start + cursor.size; - } + /* ttm_resource_ioremap only supports contiguous memory */ + if (mem->mem_type == TTM_PL_VRAM && + !(mem->placement & TTM_PL_FLAG_CONTIGUOUS)) + return false; - return end <= adev->gmc.visible_vram_size; + return true; } /* @@ -471,14 +486,16 @@ if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL)) { + amdgpu_bo_move_notify(bo, evict, new_mem); ttm_bo_move_null(bo, new_mem); - goto out; + return 0; } if (old_mem->mem_type == TTM_PL_SYSTEM && (new_mem->mem_type == TTM_PL_TT || new_mem->mem_type == AMDGPU_PL_PREEMPT)) { + amdgpu_bo_move_notify(bo, evict, new_mem); ttm_bo_move_null(bo, new_mem); - goto out; + return 0; } if ((old_mem->mem_type == TTM_PL_TT || old_mem->mem_type == AMDGPU_PL_PREEMPT) && @@ -488,9 +505,10 @@ return r; amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm); + amdgpu_bo_move_notify(bo, evict, new_mem); ttm_resource_free(bo, &bo->resource); ttm_bo_assign_mem(bo, new_mem); - goto out; + return 0; } if (old_mem->mem_type == AMDGPU_PL_GDS || @@ -502,8 +520,9 @@ new_mem->mem_type == AMDGPU_PL_OA || new_mem->mem_type == AMDGPU_PL_DOORBELL) { /* Nothing to save here */ + amdgpu_bo_move_notify(bo, evict, new_mem); ttm_bo_move_null(bo, new_mem); - goto out; + return 0; } if (bo->type == ttm_bo_type_device && @@ -515,27 +534,28 @@ abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; } - if (adev->mman.buffer_funcs_enabled) { - if (((old_mem->mem_type == TTM_PL_SYSTEM && - new_mem->mem_type == TTM_PL_VRAM) || - (old_mem->mem_type == TTM_PL_VRAM && - new_mem->mem_type == TTM_PL_SYSTEM))) { - hop->fpfn = 0; - hop->lpfn = 0; - hop->mem_type = TTM_PL_TT; - hop->flags = TTM_PL_FLAG_TEMPORARY; - return -EMULTIHOP; - } + if (adev->mman.buffer_funcs_enabled && + ((old_mem->mem_type == TTM_PL_SYSTEM && + new_mem->mem_type == TTM_PL_VRAM) || + (old_mem->mem_type == TTM_PL_VRAM && + new_mem->mem_type == TTM_PL_SYSTEM))) { + hop->fpfn = 0; + hop->lpfn = 0; + hop->mem_type = TTM_PL_TT; + hop->flags = TTM_PL_FLAG_TEMPORARY; + return -EMULTIHOP; + } + amdgpu_bo_move_notify(bo, evict, new_mem); + if (adev->mman.buffer_funcs_enabled) r = amdgpu_move_blit(bo, evict, new_mem, old_mem); - } else { + else r = -ENODEV; - } if (r) { /* Check that all memory is CPU accessible */ - if (!amdgpu_mem_visible(adev, old_mem) || - !amdgpu_mem_visible(adev, new_mem)) { + if (!amdgpu_res_copyable(adev, old_mem) || + !amdgpu_res_copyable(adev, new_mem)) { pr_err("Move buffer fallback to memcpy unavailable\n"); return r; } @@ -545,11 +565,10 @@ return r; } - trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); -out: - /* update statistics */ + /* update statistics after the move */ + if (evict) + atomic64_inc(&adev->num_evictions); atomic64_add(bo->base.size, &adev->num_bytes_moved); - amdgpu_bo_move_notify(bo, evict); return 0; } @@ -562,7 +581,6 @@ struct ttm_resource *mem) { struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); - size_t bus_size = (size_t)mem->size; switch (mem->mem_type) { case TTM_PL_SYSTEM: @@ -573,9 +591,6 @@ break; case TTM_PL_VRAM: mem->bus.offset = mem->start << PAGE_SHIFT; - /* check if it's visible */ - if ((mem->bus.offset + bus_size) > adev->gmc.visible_vram_size) - return -EINVAL; if (adev->mman.aper_base_kaddr && mem->placement & TTM_PL_FLAG_CONTIGUOUS) @@ -869,6 +884,7 @@ amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages, gtt->ttm.dma_address, flags); } + gtt->bound = true; } /* @@ -1554,7 +1570,7 @@ static void amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo) { - amdgpu_bo_move_notify(bo, false); + amdgpu_bo_move_notify(bo, false, NULL); } static struct ttm_device_funcs amdgpu_bo_driver = { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -139,6 +139,9 @@ int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr, uint64_t start); +bool amdgpu_res_cpu_visible(struct amdgpu_device *adev, + struct ttm_resource *res); + int amdgpu_ttm_init(struct amdgpu_device *adev); void amdgpu_ttm_fini(struct amdgpu_device *adev); void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c @@ -175,6 +175,7 @@ } kfree(err_data->err_addr); + err_data->err_addr = NULL; return AMDGPU_RAS_SUCCESS; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c @@ -766,6 +766,9 @@ { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + if (amdgpu_in_reset(adev) || adev->in_s0ix || adev->in_suspend) + return 0; + return umsch_mm_test(adev); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -743,7 +743,8 @@ uint32_t created = 0; uint32_t allocated = 0; uint32_t tmp, handle = 0; - uint32_t *size = &tmp; + uint32_t dummy = 0xffffffff; + uint32_t *size = &dummy; unsigned int idx; int i, r = 0; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -137,6 +137,10 @@ } } + /* from vcn4 and above, only unified queue is used */ + adev->vcn.using_unified_queue = + amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0); + hdr = (const struct common_firmware_header *)adev->vcn.fw->data; adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version); @@ -261,18 +265,6 @@ return 0; } -/* from vcn4 and above, only unified queue is used */ -static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring) -{ - struct amdgpu_device *adev = ring->adev; - bool ret = false; - - if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0)) - ret = true; - - return ret; -} - bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type type, uint32_t vcn_instance) { bool ret = false; @@ -382,7 +374,9 @@ for (i = 0; i < adev->vcn.num_enc_rings; ++i) fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]); - if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { + /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */ + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG && + !adev->vcn.using_unified_queue) { struct dpg_pause_state new_state; if (fence[j] || @@ -428,7 +422,9 @@ amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, AMD_PG_STATE_UNGATE); - if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { + /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */ + if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG && + !adev->vcn.using_unified_queue) { struct dpg_pause_state new_state; if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) { @@ -454,8 +450,12 @@ void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) { + struct amdgpu_device *adev = ring->adev; + + /* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */ if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG && - ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) + ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC && + !adev->vcn.using_unified_queue) atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt); atomic_dec(&ring->adev->vcn.total_submission_cnt); @@ -709,12 +709,11 @@ struct amdgpu_job *job; struct amdgpu_ib *ib; uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr); - bool sq = amdgpu_vcn_using_unified_queue(ring); uint32_t *ib_checksum; uint32_t ib_pack_in_dw; int i, r; - if (sq) + if (adev->vcn.using_unified_queue) ib_size_dw += 8; r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, @@ -727,7 +726,7 @@ ib->length_dw = 0; /* single queue headers */ - if (sq) { + if (adev->vcn.using_unified_queue) { ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / sizeof(uint32_t) + 4 + 2; /* engine info + decoding ib in dw */ ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, ib_pack_in_dw, false); @@ -746,7 +745,7 @@ for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - if (sq) + if (adev->vcn.using_unified_queue) amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, ib_pack_in_dw); r = amdgpu_job_submit_direct(job, ring, &f); @@ -836,15 +835,15 @@ struct dma_fence **fence) { unsigned int ib_size_dw = 16; + struct amdgpu_device *adev = ring->adev; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; uint32_t *ib_checksum = NULL; uint64_t addr; - bool sq = amdgpu_vcn_using_unified_queue(ring); int i, r; - if (sq) + if (adev->vcn.using_unified_queue) ib_size_dw += 8; r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, @@ -858,7 +857,7 @@ ib->length_dw = 0; - if (sq) + if (adev->vcn.using_unified_queue) ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true); ib->ptr[ib->length_dw++] = 0x00000018; @@ -880,7 +879,7 @@ for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - if (sq) + if (adev->vcn.using_unified_queue) amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11); r = amdgpu_job_submit_direct(job, ring, &f); @@ -903,15 +902,15 @@ struct dma_fence **fence) { unsigned int ib_size_dw = 16; + struct amdgpu_device *adev = ring->adev; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; uint32_t *ib_checksum = NULL; uint64_t addr; - bool sq = amdgpu_vcn_using_unified_queue(ring); int i, r; - if (sq) + if (adev->vcn.using_unified_queue) ib_size_dw += 8; r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL, @@ -925,7 +924,7 @@ ib->length_dw = 0; - if (sq) + if (adev->vcn.using_unified_queue) ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true); ib->ptr[ib->length_dw++] = 0x00000018; @@ -947,7 +946,7 @@ for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - if (sq) + if (adev->vcn.using_unified_queue) amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11); r = amdgpu_job_submit_direct(job, ring, &f); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -287,6 +287,7 @@ uint16_t inst_mask; uint8_t num_inst_per_aid; + bool using_unified_queue; }; struct amdgpu_fw_shared_rb_ptrs_struct { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "amdgpu.h" @@ -314,7 +315,13 @@ return 0; } afb = to_amdgpu_framebuffer(new_state->fb); - obj = new_state->fb->obj[0]; + + obj = drm_gem_fb_get_obj(new_state->fb, 0); + if (!obj) { + DRM_ERROR("Failed to get obj from framebuffer\n"); + return -EINVAL; + } + rbo = gem_to_amdgpu_bo(obj); adev = amdgpu_ttm_adev(rbo->tbo.bdev); @@ -368,12 +375,19 @@ struct drm_plane_state *old_state) { struct amdgpu_bo *rbo; + struct drm_gem_object *obj; int r; if (!old_state->fb) return; - rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]); + obj = drm_gem_fb_get_obj(old_state->fb, 0); + if (!obj) { + DRM_ERROR("Failed to get obj from framebuffer\n"); + return; + } + + rbo = gem_to_amdgpu_bo(obj); r = amdgpu_bo_reserve(rbo, false); if (unlikely(r)) { DRM_ERROR("failed to reserve rbo before unpin\n"); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1559,6 +1559,37 @@ trace_amdgpu_vm_bo_map(bo_va, mapping); } +/* Validate operation parameters to prevent potential abuse */ +static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev, + struct amdgpu_bo *bo, + uint64_t saddr, + uint64_t offset, + uint64_t size) +{ + uint64_t tmp, lpfn; + + if (saddr & AMDGPU_GPU_PAGE_MASK + || offset & AMDGPU_GPU_PAGE_MASK + || size & AMDGPU_GPU_PAGE_MASK) + return -EINVAL; + + if (check_add_overflow(saddr, size, &tmp) + || check_add_overflow(offset, size, &tmp) + || size == 0 /* which also leads to end < begin */) + return -EINVAL; + + /* make sure object fit at this offset */ + if (bo && offset + size > amdgpu_bo_size(bo)) + return -EINVAL; + + /* Ensure last pfn not exceed max_pfn */ + lpfn = (saddr + size - 1) >> AMDGPU_GPU_PAGE_SHIFT; + if (lpfn >= adev->vm_manager.max_pfn) + return -EINVAL; + + return 0; +} + /** * amdgpu_vm_bo_map - map bo inside a vm * @@ -1585,21 +1616,14 @@ struct amdgpu_bo *bo = bo_va->base.bo; struct amdgpu_vm *vm = bo_va->base.vm; uint64_t eaddr; + int r; - /* validate the parameters */ - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) - return -EINVAL; - if (saddr + size <= saddr || offset + size <= offset) - return -EINVAL; - - /* make sure object fit at this offset */ - eaddr = saddr + size - 1; - if ((bo && offset + size > amdgpu_bo_size(bo)) || - (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) - return -EINVAL; + r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); + if (r) + return r; saddr /= AMDGPU_GPU_PAGE_SIZE; - eaddr /= AMDGPU_GPU_PAGE_SIZE; + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr); if (tmp) { @@ -1652,17 +1676,9 @@ uint64_t eaddr; int r; - /* validate the parameters */ - if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) - return -EINVAL; - if (saddr + size <= saddr || offset + size <= offset) - return -EINVAL; - - /* make sure object fit at this offset */ - eaddr = saddr + size - 1; - if ((bo && offset + size > amdgpu_bo_size(bo)) || - (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) - return -EINVAL; + r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); + if (r) + return r; /* Allocate all the needed memory */ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); @@ -1676,7 +1692,7 @@ } saddr /= AMDGPU_GPU_PAGE_SIZE; - eaddr /= AMDGPU_GPU_PAGE_SIZE; + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; mapping->start = saddr; mapping->last = eaddr; @@ -1763,10 +1779,14 @@ struct amdgpu_bo_va_mapping *before, *after, *tmp, *next; LIST_HEAD(removed); uint64_t eaddr; + int r; + + r = amdgpu_vm_verify_parameters(adev, NULL, saddr, 0, size); + if (r) + return r; - eaddr = saddr + size - 1; saddr /= AMDGPU_GPU_PAGE_SIZE; - eaddr /= AMDGPU_GPU_PAGE_SIZE; + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; /* Allocate all the needed memory */ before = kzalloc(sizeof(*before), GFP_KERNEL); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c @@ -390,6 +390,12 @@ struct amdgpu_vpe *vpe = &adev->vpe; int ret; + /* Power on VPE */ + ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, + AMD_PG_STATE_UNGATE); + if (ret) + return ret; + ret = vpe_load_microcode(vpe); if (ret) return ret; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c @@ -62,6 +62,11 @@ adev->doorbell_index.max_assignment = AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT << 1; } +static bool aqua_vanjaram_xcp_vcn_shared(struct amdgpu_device *adev) +{ + return (adev->xcp_mgr->num_xcps > adev->vcn.num_vcn_inst); +} + static void aqua_vanjaram_set_xcp_id(struct amdgpu_device *adev, uint32_t inst_idx, struct amdgpu_ring *ring) { @@ -87,7 +92,7 @@ case AMDGPU_RING_TYPE_VCN_ENC: case AMDGPU_RING_TYPE_VCN_JPEG: ip_blk = AMDGPU_XCP_VCN; - if (adev->xcp_mgr->mode == AMDGPU_CPX_PARTITION_MODE) + if (aqua_vanjaram_xcp_vcn_shared(adev)) inst_mask = 1 << (inst_idx * 2); break; default: @@ -140,10 +145,12 @@ aqua_vanjaram_xcp_gpu_sched_update(adev, ring, ring->xcp_id); - /* VCN is shared by two partitions under CPX MODE */ + /* VCN may be shared by two partitions under CPX MODE in certain + * configs. + */ if ((ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC || - ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) && - adev->xcp_mgr->mode == AMDGPU_CPX_PARTITION_MODE) + ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) && + aqua_vanjaram_xcp_vcn_shared(adev)) aqua_vanjaram_xcp_gpu_sched_update(adev, ring, ring->xcp_id + 1); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atom.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/atom.c @@ -313,7 +313,7 @@ DEBUG("IMM 0x%02X\n", val); return val; } - return 0; + break; case ATOM_ARG_PLL: idx = U8(*ptr); (*ptr)++; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -9194,7 +9194,7 @@ 7 + /* PIPELINE_SYNC */ SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + - 2 + /* VM_FLUSH */ + 4 + /* VM_FLUSH */ 8 + /* FENCE for VM_FLUSH */ 20 + /* GDS switch */ 4 + /* double SWITCH_BUFFER, @@ -9285,7 +9285,6 @@ 7 + /* gfx_v10_0_ring_emit_pipeline_sync */ SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + - 2 + /* gfx_v10_0_ring_emit_vm_flush */ 8 + 8 + 8, /* gfx_v10_0_ring_emit_fence_kiq x3 for user fence, vm fence */ .emit_ib_size = 7, /* gfx_v10_0_ring_emit_ib_compute */ .emit_ib = gfx_v10_0_ring_emit_ib_compute, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1630,7 +1630,7 @@ active_rb_bitmap |= (0x3 << (i * rb_bitmap_width_per_sa)); } - active_rb_bitmap |= global_active_rb_bitmap; + active_rb_bitmap &= global_active_rb_bitmap; adev->gfx.config.backend_enable_mask = active_rb_bitmap; adev->gfx.config.num_rbs = hweight32(active_rb_bitmap); } @@ -6110,7 +6110,7 @@ 7 + /* PIPELINE_SYNC */ SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + - 2 + /* VM_FLUSH */ + 4 + /* VM_FLUSH */ 8 + /* FENCE for VM_FLUSH */ 20 + /* GDS switch */ 5 + /* COND_EXEC */ @@ -6195,7 +6195,6 @@ 7 + /* gfx_v11_0_ring_emit_pipeline_sync */ SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + - 2 + /* gfx_v11_0_ring_emit_vm_flush */ 8 + 8 + 8, /* gfx_v11_0_ring_emit_fence_kiq x3 for user fence, vm fence */ .emit_ib_size = 7, /* gfx_v11_0_ring_emit_ib_compute */ .emit_ib = gfx_v11_0_ring_emit_ib_compute, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -6991,7 +6991,6 @@ 7 + /* gfx_v9_0_ring_emit_pipeline_sync */ SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + - 2 + /* gfx_v9_0_ring_emit_vm_flush */ 8 + 8 + 8 + /* gfx_v9_0_ring_emit_fence x3 for user fence, vm fence */ 7 + /* gfx_v9_0_emit_mem_sync */ 5 + /* gfx_v9_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */ @@ -7029,7 +7028,6 @@ 7 + /* gfx_v9_0_ring_emit_pipeline_sync */ SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + - 2 + /* gfx_v9_0_ring_emit_vm_flush */ 8 + 8 + 8, /* gfx_v9_0_ring_emit_fence_kiq x3 for user fence, vm fence */ .emit_ib_size = 7, /* gfx_v9_0_ring_emit_ib_compute */ .emit_fence = gfx_v9_0_ring_emit_fence_kiq, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -426,16 +426,16 @@ static int gfx_v9_4_3_init_microcode(struct amdgpu_device *adev) { - const char *chip_name; + char ucode_prefix[15]; int r; - chip_name = "gc_9_4_3"; + amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); - r = gfx_v9_4_3_init_rlc_microcode(adev, chip_name); + r = gfx_v9_4_3_init_rlc_microcode(adev, ucode_prefix); if (r) return r; - r = gfx_v9_4_3_init_cp_compute_microcode(adev, chip_name); + r = gfx_v9_4_3_init_cp_compute_microcode(adev, ucode_prefix); if (r) return r; @@ -4121,9 +4121,10 @@ static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev, struct amdgpu_cu_info *cu_info) { - int i, j, k, counter, xcc_id, active_cu_number = 0; - u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; + int i, j, k, prev_counter, counter, xcc_id, active_cu_number = 0; + u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0, tmp; unsigned disable_masks[4 * 4]; + bool is_symmetric_cus; if (!adev || !cu_info) return -EINVAL; @@ -4141,6 +4142,7 @@ mutex_lock(&adev->grbm_idx_mutex); for (xcc_id = 0; xcc_id < NUM_XCC(adev->gfx.xcc_mask); xcc_id++) { + is_symmetric_cus = true; for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { mask = 1; @@ -4168,6 +4170,15 @@ ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); cu_info->ao_cu_bitmap[i][j] = ao_bitmap; } + if (i && is_symmetric_cus && prev_counter != counter) + is_symmetric_cus = false; + prev_counter = counter; + } + if (is_symmetric_cus) { + tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_DEBUG); + tmp = REG_SET_FIELD(tmp, CP_CPC_DEBUG, CPC_HARVESTING_RELAUNCH_DISABLE, 1); + tmp = REG_SET_FIELD(tmp, CP_CPC_DEBUG, CPC_HARVESTING_DISPATCH_DISABLE, 1); + WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_DEBUG, tmp); } gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, xcc_id); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -570,6 +570,7 @@ adev->mmhub.funcs = &mmhub_v3_0_2_funcs; break; case IP_VERSION(3, 3, 0): + case IP_VERSION(3, 3, 1): adev->mmhub.funcs = &mmhub_v3_3_funcs; break; default: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c @@ -98,16 +98,16 @@ switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) { case IP_VERSION(3, 3, 0): - mmhub_cid = mmhub_client_ids_v3_3[cid][rw]; + case IP_VERSION(3, 3, 1): + mmhub_cid = cid < ARRAY_SIZE(mmhub_client_ids_v3_3) ? + mmhub_client_ids_v3_3[cid][rw] : + cid == 0x140 ? "UMSCH" : NULL; break; default: mmhub_cid = NULL; break; } - if (!mmhub_cid && cid == 0x140) - mmhub_cid = "UMSCH"; - dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", mmhub_cid ? mmhub_cid : "unknown", cid); dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n", --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -2017,10 +2017,13 @@ struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { - uint32_t instance; + int instance; DRM_DEBUG("IH: SDMA trap\n"); instance = sdma_v4_0_irq_id_to_seq(entry->client_id); + if (instance < 0) + return instance; + switch (entry->ring_id) { case 0: amdgpu_fence_process(&adev->sdma.instance[instance].ring); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c @@ -366,7 +366,8 @@ u32 ref_and_mask = 0; const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg; - ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 << ring->me; + ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 + << (ring->me % adev->sdma.num_inst_per_aid); sdma_v4_4_2_wait_reg_mem(ring, 0, 1, adev->nbio.funcs->get_hdp_flush_done_offset(adev), @@ -429,16 +430,11 @@ struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES]; u32 doorbell_offset, doorbell; u32 rb_cntl, ib_cntl; - int i, unset = 0; + int i; for_each_inst(i, inst_mask) { sdma[i] = &adev->sdma.instance[i].ring; - if ((adev->mman.buffer_funcs_ring == sdma[i]) && unset != 1) { - amdgpu_ttm_set_buffer_funcs_status(adev, false); - unset = 1; - } - rb_cntl = RREG32_SDMA(i, regSDMA_GFX_RB_CNTL); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA_GFX_RB_CNTL, RB_ENABLE, 0); WREG32_SDMA(i, regSDMA_GFX_RB_CNTL, rb_cntl); @@ -485,20 +481,10 @@ static void sdma_v4_4_2_inst_page_stop(struct amdgpu_device *adev, uint32_t inst_mask) { - struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES]; u32 rb_cntl, ib_cntl; int i; - bool unset = false; for_each_inst(i, inst_mask) { - sdma[i] = &adev->sdma.instance[i].page; - - if ((adev->mman.buffer_funcs_ring == sdma[i]) && - (!unset)) { - amdgpu_ttm_set_buffer_funcs_status(adev, false); - unset = true; - } - rb_cntl = RREG32_SDMA(i, regSDMA_PAGE_RB_CNTL); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA_PAGE_RB_CNTL, RB_ENABLE, 0); @@ -948,13 +934,7 @@ r = amdgpu_ring_test_helper(page); if (r) return r; - - if (adev->mman.buffer_funcs_ring == page) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return r; @@ -1621,19 +1601,9 @@ u32 sdma_cntl; sdma_cntl = RREG32_SDMA(type, regSDMA_CNTL); - switch (state) { - case AMDGPU_IRQ_STATE_DISABLE: - sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL, - DRAM_ECC_INT_ENABLE, 0); - WREG32_SDMA(type, regSDMA_CNTL, sdma_cntl); - break; - /* sdma ecc interrupt is enabled by default - * driver doesn't need to do anything to - * enable the interrupt */ - case AMDGPU_IRQ_STATE_ENABLE: - default: - break; - } + sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL, DRAM_ECC_INT_ENABLE, + state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0); + WREG32_SDMA(type, regSDMA_CNTL, sdma_cntl); return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -292,17 +292,21 @@ u32 ref_and_mask = 0; const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg; - ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 << ring->me; + if (ring->me > 1) { + amdgpu_asic_flush_hdp(adev, ring); + } else { + ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 << ring->me; - amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | - SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(1) | - SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */ - amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_done_offset(adev)) << 2); - amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_req_offset(adev)) << 2); - amdgpu_ring_write(ring, ref_and_mask); /* reference */ - amdgpu_ring_write(ring, ref_and_mask); /* mask */ - amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) | - SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */ + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | + SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(1) | + SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */ + amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_done_offset(adev)) << 2); + amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_req_offset(adev)) << 2); + amdgpu_ring_write(ring, ref_and_mask); /* reference */ + amdgpu_ring_write(ring, ref_and_mask); /* mask */ + amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) | + SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */ + } } /** --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c @@ -92,7 +92,7 @@ adev->ip_blocks[i].status.hw = false; } - return r; + return 0; } static int --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/soc21.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -450,10 +450,8 @@ { switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { case IP_VERSION(11, 0, 0): - return amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC); case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 3): - return false; default: return true; } @@ -714,7 +712,10 @@ AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_JPEG | AMD_PG_SUPPORT_GFX_PG; - adev->external_rev_id = adev->rev_id + 0x1; + if (adev->rev_id == 0) + adev->external_rev_id = 0x1; + else + adev->external_rev_id = adev->rev_id + 0x10; break; default: /* FIXME: not supported yet */ @@ -832,10 +833,35 @@ return soc21_common_hw_fini(adev); } +static bool soc21_need_reset_on_resume(struct amdgpu_device *adev) +{ + u32 sol_reg1, sol_reg2; + + /* Will reset for the following suspend abort cases. + * 1) Only reset dGPU side. + * 2) S3 suspend got aborted and TOS is active. + */ + if (!(adev->flags & AMD_IS_APU) && adev->in_s3 && + !adev->suspend_complete) { + sol_reg1 = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81); + msleep(100); + sol_reg2 = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81); + + return (sol_reg1 != sol_reg2); + } + + return false; +} + static int soc21_common_resume(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + if (soc21_need_reset_on_resume(adev)) { + dev_info(adev->dev, "S3 suspend aborted, resetting..."); + soc21_asic_reset(adev); + } + return soc21_common_hw_init(adev); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c @@ -225,6 +225,8 @@ WREG32_SOC15(VCN, 0, regVCN_UMSCH_RB_SIZE, ring->ring_size); + ring->wptr = 0; + data = RREG32_SOC15(VCN, 0, regVCN_RB_ENABLE); data &= ~(VCN_RB_ENABLE__AUDIO_RB_EN_MASK); WREG32_SOC15(VCN, 0, regVCN_RB_ENABLE, data); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -778,8 +778,8 @@ * nodes, but not more than args->num_of_nodes as that is * the amount of memory allocated by user */ - pa = kzalloc((sizeof(struct kfd_process_device_apertures) * - args->num_of_nodes), GFP_KERNEL); + pa = kcalloc(args->num_of_nodes, sizeof(struct kfd_process_device_apertures), + GFP_KERNEL); if (!pa) return -ENOMEM; @@ -1138,7 +1138,7 @@ goto err_unlock; } offset = dev->adev->rmmio_remap.bus_addr; - if (!offset) { + if (!offset || (PAGE_SIZE > 4096)) { err = -ENOMEM; goto err_unlock; } @@ -1522,7 +1522,7 @@ /* Find a KFD GPU device that supports the get_dmabuf_info query */ for (i = 0; kfd_topology_enum_kfd_devices(i, &dev) == 0; i++) - if (dev) + if (dev && !kfd_devcgroup_check_permission(dev)) break; if (!dev) return -EINVAL; @@ -1544,7 +1544,7 @@ if (xcp_id >= 0) args->gpu_id = dmabuf_adev->kfd.dev->nodes[xcp_id]->id; else - args->gpu_id = dmabuf_adev->kfd.dev->nodes[0]->id; + args->gpu_id = dev->id; args->flags = flags; /* Copy metadata buffer to user mode */ @@ -2306,7 +2306,7 @@ return -EINVAL; } offset = pdd->dev->adev->rmmio_remap.bus_addr; - if (!offset) { + if (!offset || (PAGE_SIZE > 4096)) { pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n"); return -ENOMEM; } @@ -3347,6 +3347,9 @@ if (vma->vm_end - vma->vm_start != PAGE_SIZE) return -EINVAL; + if (PAGE_SIZE > 4096) + return -EINVAL; + address = dev->adev->rmmio_remap.bus_addr; vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -405,15 +405,8 @@ f2g = &gfx_v11_kfd2kgd; break; case IP_VERSION(11, 0, 3): - if ((adev->pdev->device == 0x7460 && - adev->pdev->revision == 0x00) || - (adev->pdev->device == 0x7461 && - adev->pdev->revision == 0x00)) - /* Note: Compiler version is 11.0.5 while HW version is 11.0.3 */ - gfx_target_version = 110005; - else - /* Note: Compiler version is 11.0.1 while HW version is 11.0.3 */ - gfx_target_version = 110001; + /* Note: Compiler version is 11.0.1 while HW version is 11.0.3 */ + gfx_target_version = 110001; f2g = &gfx_v11_kfd2kgd; break; case IP_VERSION(11, 5, 0): @@ -944,7 +937,6 @@ { struct kfd_node *node; int i; - int count; if (!kfd->init_complete) return; @@ -952,12 +944,10 @@ /* for runtime suspend, skip locking kfd */ if (!run_pm) { mutex_lock(&kfd_processes_mutex); - count = ++kfd_locked; - mutex_unlock(&kfd_processes_mutex); - /* For first KFD device suspend all the KFD processes */ - if (count == 1) + if (++kfd_locked == 1) kfd_suspend_all_processes(); + mutex_unlock(&kfd_processes_mutex); } for (i = 0; i < kfd->num_nodes; i++) { @@ -968,7 +958,7 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm) { - int ret, count, i; + int ret, i; if (!kfd->init_complete) return 0; @@ -982,12 +972,10 @@ /* for runtime resume, skip unlocking kfd */ if (!run_pm) { mutex_lock(&kfd_processes_mutex); - count = --kfd_locked; - mutex_unlock(&kfd_processes_mutex); - - WARN_ONCE(count < 0, "KFD suspend / resume ref. error"); - if (count == 0) + if (--kfd_locked == 0) ret = kfd_resume_all_processes(); + WARN_ONCE(kfd_locked < 0, "KFD suspend / resume ref. error"); + mutex_unlock(&kfd_processes_mutex); } return ret; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1997,6 +1997,7 @@ dev_err(dev, "HIQ MQD's queue_doorbell_id0 is not 0, Queue preemption time out\n"); while (halt_if_hws_hang) schedule(); + kfd_hws_hang(dqm); return -ETIME; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c @@ -336,7 +336,8 @@ break; } kfd_signal_event_interrupt(pasid, context_id0 & 0x7fffff, 23); - } else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) { + } else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE && + KFD_DBG_EC_TYPE_IS_PACKET(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0))) { kfd_set_dbg_ev_from_interrupt(dev, pasid, KFD_DEBUG_DOORBELL_ID(context_id0), KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)), --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c @@ -325,7 +325,8 @@ /* CP */ if (source_id == SOC15_INTSRC_CP_END_OF_PIPE) kfd_signal_event_interrupt(pasid, context_id0, 32); - else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) + else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE && + KFD_DBG_EC_TYPE_IS_PACKET(KFD_CTXID0_CP_BAD_OP_ECODE(context_id0))) kfd_set_dbg_ev_from_interrupt(dev, pasid, KFD_CTXID0_DOORBELL_ID(context_id0), KFD_EC_MASK(KFD_CTXID0_CP_BAD_OP_ECODE(context_id0)), --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c @@ -385,7 +385,8 @@ break; } kfd_signal_event_interrupt(pasid, sq_int_data, 24); - } else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) { + } else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE && + KFD_DBG_EC_TYPE_IS_PACKET(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0))) { kfd_set_dbg_ev_from_interrupt(dev, pasid, KFD_DEBUG_DOORBELL_ID(context_id0), KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)), --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -509,10 +509,19 @@ start = start_mgr << PAGE_SHIFT; end = (last_mgr + 1) << PAGE_SHIFT; + r = amdgpu_amdkfd_reserve_mem_limit(node->adev, + prange->npages * PAGE_SIZE, + KFD_IOC_ALLOC_MEM_FLAGS_VRAM, + node->xcp ? node->xcp->id : 0); + if (r) { + dev_dbg(node->adev->dev, "failed to reserve VRAM, r: %ld\n", r); + return -ENOSPC; + } + r = svm_range_vram_node_new(node, prange, true); if (r) { dev_dbg(node->adev->dev, "fail %ld to alloc vram\n", r); - return r; + goto out; } ttm_res_offset = (start_mgr - prange->start + prange->offset) << PAGE_SHIFT; @@ -545,6 +554,11 @@ svm_range_vram_node_free(prange); } +out: + amdgpu_amdkfd_unreserve_mem_limit(node->adev, + prange->npages * PAGE_SIZE, + KFD_IOC_ALLOC_MEM_FLAGS_VRAM, + node->xcp ? node->xcp->id : 0); return r < 0 ? r : 0; } @@ -1009,7 +1023,7 @@ if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(9, 0, 1)) return -EINVAL; - if (adev->gmc.is_app_apu) + if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) return 0; pgmap = &kfddev->pgmap; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -1473,7 +1473,7 @@ static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev) { - return KFD_GC_VERSION(dev) > IP_VERSION(9, 4, 2) || + return KFD_GC_VERSION(dev) >= IP_VERSION(9, 4, 2) || (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && dev->sdma_fw_version >= 18) || KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -819,9 +819,9 @@ mutex_lock(&kfd_processes_mutex); if (kfd_is_locked()) { - mutex_unlock(&kfd_processes_mutex); pr_debug("KFD is locked! Cannot create process"); - return ERR_PTR(-EINVAL); + process = ERR_PTR(-EINVAL); + goto out; } /* A prior open of /dev/kfd could have already created the process. */ @@ -829,6 +829,14 @@ if (process) { pr_debug("Process already found\n"); } else { + /* If the process just called exec(3), it is possible that the + * cleanup of the kfd_process (following the release of the mm + * of the old process image) is still in the cleanup work queue. + * Make sure to drain any job before trying to recreate any + * resource for this process. + */ + flush_workqueue(kfd_process_wq); + process = create_process(thread); if (IS_ERR(process)) goto out; @@ -1922,6 +1930,8 @@ rcu_read_lock(); ef = dma_fence_get_rcu_safe(&p->ef); rcu_read_unlock(); + if (!ef) + return -EINVAL; ret = dma_fence_signal(ef); dma_fence_put(ef); @@ -1949,10 +1959,9 @@ * they are responsible stopping the queues and scheduling * the restore work. */ - if (!signal_eviction_fence(p)) - queue_delayed_work(kfd_restore_wq, &p->restore_work, - msecs_to_jiffies(PROCESS_RESTORE_TIME_MS)); - else + if (signal_eviction_fence(p) || + mod_delayed_work(kfd_restore_wq, &p->restore_work, + msecs_to_jiffies(PROCESS_RESTORE_TIME_MS))) kfd_process_restore_queues(p); pr_debug("Finished evicting pasid 0x%x\n", p->pasid); @@ -2011,9 +2020,9 @@ if (ret) { pr_debug("Failed to restore BOs of pasid 0x%x, retry after %d ms\n", p->pasid, PROCESS_BACK_OFF_TIME_MS); - ret = queue_delayed_work(kfd_restore_wq, &p->restore_work, - msecs_to_jiffies(PROCESS_BACK_OFF_TIME_MS)); - WARN(!ret, "reschedule restore work failed\n"); + if (mod_delayed_work(kfd_restore_wq, &p->restore_work, + msecs_to_jiffies(PROCESS_RESTORE_TIME_MS))) + kfd_process_restore_queues(p); } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -2617,7 +2617,8 @@ return -1; } - if (node->adev->gmc.is_app_apu) + if (node->adev->gmc.is_app_apu || + node->adev->flags & AMD_IS_APU) return 0; if (prange->preferred_loc == gpuid || @@ -3335,7 +3336,8 @@ goto out; } - if (bo_node->adev->gmc.is_app_apu) { + if (bo_node->adev->gmc.is_app_apu || + bo_node->adev->flags & AMD_IS_APU) { best_loc = 0; goto out; } @@ -3424,7 +3426,7 @@ mm, KFD_MIGRATE_TRIGGER_PREFETCH); *migrated = !r; - return r; + return 0; } int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.h @@ -201,7 +201,8 @@ * is initialized to not 0 when page migration register device memory. */ #define KFD_IS_SVM_API_SUPPORTED(adev) ((adev)->kfd.pgmap.type != 0 ||\ - (adev)->gmc.is_app_apu) + (adev)->gmc.is_app_apu ||\ + ((adev)->flags & AMD_IS_APU)) void svm_range_bo_unref_async(struct svm_range_bo *svm_bo); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -147,6 +147,9 @@ #define FIRMWARE_DCN_35_DMUB "amdgpu/dcn_3_5_dmcub.bin" MODULE_FIRMWARE(FIRMWARE_DCN_35_DMUB); +#define FIRMWARE_DCN_351_DMUB "amdgpu/dcn_3_5_1_dmcub.bin" +MODULE_FIRMWARE(FIRMWARE_DCN_351_DMUB); + /* Number of bytes in PSP header for firmware. */ #define PSP_HEADER_BYTES 0x100 @@ -270,7 +273,7 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, u32 *vbl, u32 *position) { - u32 v_blank_start, v_blank_end, h_position, v_position; + u32 v_blank_start = 0, v_blank_end = 0, h_position = 0, v_position = 0; struct amdgpu_crtc *acrtc = NULL; struct dc *dc = adev->dm.dc; @@ -844,7 +847,7 @@ */ static void dm_dmub_outbox1_low_irq(void *interrupt_params) { - struct dmub_notification notify; + struct dmub_notification notify = {0}; struct common_irq_params *irq_params = interrupt_params; struct amdgpu_device *adev = irq_params->adev; struct amdgpu_display_manager *dm = &adev->dm; @@ -1929,17 +1932,15 @@ adev->dm.hdcp_workqueue = NULL; } - if (adev->dm.dc) + if (adev->dm.dc) { dc_deinit_callbacks(adev->dm.dc); - - if (adev->dm.dc) dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv); - - if (dc_enable_dmub_notifications(adev->dm.dc)) { - kfree(adev->dm.dmub_notify); - adev->dm.dmub_notify = NULL; - destroy_workqueue(adev->dm.delayed_hpd_wq); - adev->dm.delayed_hpd_wq = NULL; + if (dc_enable_dmub_notifications(adev->dm.dc)) { + kfree(adev->dm.dmub_notify); + adev->dm.dmub_notify = NULL; + destroy_workqueue(adev->dm.delayed_hpd_wq); + adev->dm.delayed_hpd_wq = NULL; + } } if (adev->dm.dmub_bo) @@ -3009,6 +3010,7 @@ dc_stream_release(dm_new_crtc_state->stream); dm_new_crtc_state->stream = NULL; } + dm_new_crtc_state->base.color_mgmt_changed = true; } for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, i) { @@ -3027,6 +3029,10 @@ /* Do mst topology probing after resuming cached state*/ drm_connector_list_iter_begin(ddev, &iter); drm_for_each_connector_iter(connector, &iter) { + + if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) + continue; + aconnector = to_amdgpu_dm_connector(connector); if (aconnector->dc_link->type != dc_connection_mst_branch || aconnector->mst_root) @@ -4778,6 +4784,9 @@ case IP_VERSION(3, 5, 0): fw_name_dmub = FIRMWARE_DCN_35_DMUB; break; + case IP_VERSION(3, 5, 1): + fw_name_dmub = FIRMWARE_DCN_351_DMUB; + break; default: /* ASIC doesn't support DMUB. */ return 0; @@ -5201,6 +5210,10 @@ * @new_plane_state: New state of @plane * @crtc_state: New state of CRTC connected to the @plane * @flip_addrs: DC flip tracking struct, which also tracts dirty rects + * @is_psr_su: Flag indicating whether Panel Self Refresh Selective Update (PSR SU) is enabled. + * If PSR SU is enabled and damage clips are available, only the regions of the screen + * that have changed will be updated. If PSR SU is not enabled, + * or if damage clips are not available, the entire screen will be updated. * @dirty_regions_changed: dirty regions changed * * For PSR SU, DC informs the DMUB uController of dirty rectangle regions @@ -5871,6 +5884,9 @@ &aconnector->base.probed_modes : &aconnector->base.modes; + if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_WRITEBACK) + return NULL; + if (aconnector->freesync_vid_base.clock != 0) return &aconnector->freesync_vid_base; @@ -6254,27 +6270,22 @@ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket); - else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || - stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || - stream->signal == SIGNAL_TYPE_EDP) { + + if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT || + stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST || + stream->signal == SIGNAL_TYPE_EDP) { // // should decide stream support vsc sdp colorimetry capability // before building vsc info packet // - stream->use_vsc_sdp_for_colorimetry = false; - if (aconnector->dc_sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { - stream->use_vsc_sdp_for_colorimetry = - aconnector->dc_sink->is_vsc_sdp_colorimetry_supported; - } else { - if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) - stream->use_vsc_sdp_for_colorimetry = true; - } + stream->use_vsc_sdp_for_colorimetry = stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 && + stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED; + if (stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) tf = TRANSFER_FUNC_GAMMA_22; mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space, tf); + aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY; - if (stream->link->psr_settings.psr_feature_enabled) - aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY; } finish: dc_sink_release(sink); @@ -6409,10 +6420,82 @@ return ret; } +/** + * DOC: panel power savings + * + * The display manager allows you to set your desired **panel power savings** + * level (between 0-4, with 0 representing off), e.g. using the following:: + * + * # echo 3 > /sys/class/drm/card0-eDP-1/amdgpu/panel_power_savings + * + * Modifying this value can have implications on color accuracy, so tread + * carefully. + */ + +static ssize_t panel_power_savings_show(struct device *device, + struct device_attribute *attr, + char *buf) +{ + struct drm_connector *connector = dev_get_drvdata(device); + struct drm_device *dev = connector->dev; + u8 val; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + val = to_dm_connector_state(connector->state)->abm_level == + ABM_LEVEL_IMMEDIATE_DISABLE ? 0 : + to_dm_connector_state(connector->state)->abm_level; + drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return sysfs_emit(buf, "%u\n", val); +} + +static ssize_t panel_power_savings_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct drm_connector *connector = dev_get_drvdata(device); + struct drm_device *dev = connector->dev; + long val; + int ret; + + ret = kstrtol(buf, 0, &val); + + if (ret) + return ret; + + if (val < 0 || val > 4) + return -EINVAL; + + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); + to_dm_connector_state(connector->state)->abm_level = val ?: + ABM_LEVEL_IMMEDIATE_DISABLE; + drm_modeset_unlock(&dev->mode_config.connection_mutex); + + drm_kms_helper_hotplug_event(dev); + + return count; +} + +static DEVICE_ATTR_RW(panel_power_savings); + +static struct attribute *amdgpu_attrs[] = { + &dev_attr_panel_power_savings.attr, + NULL +}; + +static const struct attribute_group amdgpu_group = { + .name = "amdgpu", + .attrs = amdgpu_attrs +}; + static void amdgpu_dm_connector_unregister(struct drm_connector *connector) { struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && + amdgpu_dm_abm_level < 0) + sysfs_remove_group(&connector->kdev->kobj, &amdgpu_group); + drm_dp_aux_unregister(&amdgpu_dm_connector->dm_dp_aux.aux); } @@ -6474,9 +6557,12 @@ state->vcpi_slots = 0; state->pbn = 0; - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) - state->abm_level = amdgpu_dm_abm_level ?: - ABM_LEVEL_IMMEDIATE_DISABLE; + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (amdgpu_dm_abm_level <= 0) + state->abm_level = ABM_LEVEL_IMMEDIATE_DISABLE; + else + state->abm_level = amdgpu_dm_abm_level; + } __drm_atomic_helper_connector_reset(connector, &state->base); } @@ -6514,6 +6600,14 @@ to_amdgpu_dm_connector(connector); int r; + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && + amdgpu_dm_abm_level < 0) { + r = sysfs_create_group(&connector->kdev->kobj, + &amdgpu_group); + if (r) + return r; + } + amdgpu_dm_register_backlight_device(amdgpu_dm_connector); if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) || @@ -7054,7 +7148,7 @@ struct amdgpu_dm_connector *aconnector; struct dm_connector_state *dm_conn_state; int i, j, ret; - int vcpi, pbn_div, pbn, slot_num = 0; + int vcpi, pbn_div, pbn = 0, slot_num = 0; for_each_new_connector_in_state(state, connector, new_con_state, i) { @@ -7548,7 +7642,8 @@ aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc; if (connector_type == DRM_MODE_CONNECTOR_eDP && - (dc_is_dmcu_initialized(adev->dm.dc) || adev->dm.dc->ctx->dmub_srv)) { + (dc_is_dmcu_initialized(adev->dm.dc) || + adev->dm.dc->ctx->dmub_srv) && amdgpu_dm_abm_level < 0) { drm_object_attach_property(&aconnector->base.base, adev->mode_info.abm_level_property, 0); } @@ -8630,10 +8725,10 @@ if (!drm_atomic_crtc_needs_modeset(new_crtc_state)) continue; +notify: if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) continue; -notify: aconnector = to_amdgpu_dm_connector(connector); mutex_lock(&adev->dm.audio_lock); @@ -9003,9 +9098,6 @@ trace_amdgpu_dm_atomic_commit_tail_begin(state); - if (dm->dc->caps.ips_support && dm->dc->idle_optimizations_allowed) - dc_allow_idle_optimizations(dm->dc, false); - drm_atomic_helper_update_legacy_modeset_state(dev, state); drm_dp_mst_atomic_wait_for_dependencies(state); @@ -10451,7 +10543,7 @@ struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state; struct drm_dp_mst_topology_mgr *mgr; struct drm_dp_mst_topology_state *mst_state; - struct dsc_mst_fairness_vars vars[MAX_PIPES]; + struct dsc_mst_fairness_vars vars[MAX_PIPES] = {0}; trace_amdgpu_dm_atomic_check_begin(state); @@ -11017,6 +11109,49 @@ return ret; } +static void parse_edid_displayid_vrr(struct drm_connector *connector, + struct edid *edid) +{ + u8 *edid_ext = NULL; + int i; + int j = 0; + u16 min_vfreq; + u16 max_vfreq; + + if (edid == NULL || edid->extensions == 0) + return; + + /* Find DisplayID extension */ + for (i = 0; i < edid->extensions; i++) { + edid_ext = (void *)(edid + (i + 1)); + if (edid_ext[0] == DISPLAYID_EXT) + break; + } + + if (edid_ext == NULL) + return; + + while (j < EDID_LENGTH) { + /* Get dynamic video timing range from DisplayID if available */ + if (EDID_LENGTH - j > 13 && edid_ext[j] == 0x25 && + (edid_ext[j+1] & 0xFE) == 0 && (edid_ext[j+2] == 9)) { + min_vfreq = edid_ext[j+9]; + if (edid_ext[j+1] & 7) + max_vfreq = edid_ext[j+10] + ((edid_ext[j+11] & 3) << 8); + else + max_vfreq = edid_ext[j+10]; + + if (max_vfreq && min_vfreq) { + connector->display_info.monitor_range.max_vfreq = max_vfreq; + connector->display_info.monitor_range.min_vfreq = min_vfreq; + + return; + } + } + j++; + } +} + static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector, struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info) { @@ -11138,18 +11273,31 @@ if (!adev->dm.freesync_module) goto update; - if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT - || sink->sink_signal == SIGNAL_TYPE_EDP) { + /* Some eDP panels only have the refresh rate range info in DisplayID */ + if ((connector->display_info.monitor_range.min_vfreq == 0 || + connector->display_info.monitor_range.max_vfreq == 0)) + parse_edid_displayid_vrr(connector, edid); + + if (edid && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT || + sink->sink_signal == SIGNAL_TYPE_EDP)) { bool edid_check_required = false; - if (edid) { - edid_check_required = is_dp_capable_without_timing_msa( - adev->dm.dc, - amdgpu_dm_connector); + if (is_dp_capable_without_timing_msa(adev->dm.dc, + amdgpu_dm_connector)) { + if (edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ) { + amdgpu_dm_connector->min_vfreq = connector->display_info.monitor_range.min_vfreq; + amdgpu_dm_connector->max_vfreq = connector->display_info.monitor_range.max_vfreq; + if (amdgpu_dm_connector->max_vfreq - + amdgpu_dm_connector->min_vfreq > 10) + freesync_capable = true; + } else { + edid_check_required = edid->version > 1 || + (edid->version == 1 && + edid->revision > 1); + } } - if (edid_check_required == true && (edid->version > 1 || - (edid->version == 1 && edid->revision > 1))) { + if (edid_check_required) { for (i = 0; i < 4; i++) { timing = &edid->detailed_timings[i]; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -1249,7 +1249,7 @@ size_t size, loff_t *pos) { int r; - uint8_t data[36]; + uint8_t data[36] = {0}; struct amdgpu_dm_connector *connector = file_inode(f)->i_private; struct dm_crtc_state *acrtc_state; uint32_t write_size = 36; @@ -1483,7 +1483,7 @@ const uint32_t rd_buf_size = 10; struct pipe_ctx *pipe_ctx; ssize_t result = 0; - int i, r, str_len = 30; + int i, r, str_len = 10; rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL); @@ -1495,7 +1495,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -1596,7 +1598,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -1681,7 +1685,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -1780,7 +1786,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -1865,7 +1873,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -1964,7 +1974,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2045,7 +2057,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2141,7 +2155,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2220,7 +2236,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2276,7 +2294,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2347,7 +2367,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2418,7 +2440,9 @@ for (i = 0; i < MAX_PIPES; i++) { pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i]; if (pipe_ctx->stream && - pipe_ctx->stream->link == aconnector->dc_link) + pipe_ctx->stream->link == aconnector->dc_link && + pipe_ctx->stream->sink && + pipe_ctx->stream->sink == aconnector->dc_sink) break; } @@ -2936,7 +2960,7 @@ { struct amdgpu_dm_connector *connector = data; struct dc_link *link = connector->dc_link; - u32 residency; + u32 residency = 0; link->dc->link_srv->edp_get_psr_residency(link, &residency); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -363,7 +363,7 @@ mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state); new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port); - ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload); + ret = drm_dp_add_payload_part2(mst_mgr, new_payload); if (ret) { amdgpu_dm_set_mst_status(&aconnector->mst_status, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -613,6 +613,9 @@ &connector->base, dev->mode_config.tile_property, 0); + connector->colorspace_property = master->base.colorspace_property; + if (connector->colorspace_property) + drm_connector_attach_colorspace_property(connector); drm_connector_set_path_property(connector, pathprop); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -141,9 +141,8 @@ * amdgpu_dm_psr_enable() - enable psr f/w * @stream: stream state * - * Return: true if success */ -bool amdgpu_dm_psr_enable(struct dc_stream_state *stream) +void amdgpu_dm_psr_enable(struct dc_stream_state *stream) { struct dc_link *link = stream->link; unsigned int vsync_rate_hz = 0; @@ -190,7 +189,10 @@ if (link->psr_settings.psr_version < DC_PSR_VERSION_SU_1) power_opt |= psr_power_opt_z10_static_screen; - return dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt); + dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt); + + if (link->ctx->dc->caps.ips_support) + dc_allow_idle_optimizations(link->ctx->dc, true); } /* --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.h @@ -32,7 +32,7 @@ #define AMDGPU_DM_PSR_ENTRY_DELAY 5 void amdgpu_dm_set_psr_caps(struct dc_link *link); -bool amdgpu_dm_psr_enable(struct dc_stream_state *stream); +void amdgpu_dm_psr_enable(struct dc_stream_state *stream); bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream); bool amdgpu_dm_psr_disable(struct dc_stream_state *stream); bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c @@ -76,10 +76,8 @@ static int amdgpu_dm_wb_connector_get_modes(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - - return drm_add_modes_noedid(connector, dev->mode_config.max_width, - dev->mode_config.max_height); + /* Maximum resolution supported by DWB */ + return drm_add_modes_noedid(connector, 3840, 2160); } static int amdgpu_dm_wb_prepare_job(struct drm_writeback_connector *wb_connector, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -2948,6 +2948,7 @@ result = get_integrated_info_v2_1(bp, info); break; case 2: + case 3: result = get_integrated_info_v2_2(bp, info); break; default: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -145,6 +145,10 @@ */ clk_mgr_base->clks.zstate_support = new_clocks->zstate_support; if (safe_to_lower) { + if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) { + dcn315_smu_set_dtbclk(clk_mgr, false); + clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en; + } /* check that we're not already in lower */ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { display_count = dcn315_get_active_display_cnt_wa(dc, context); @@ -160,6 +164,10 @@ } } } else { + if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) { + dcn315_smu_set_dtbclk(clk_mgr, true); + clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en; + } /* check that we're not already in D0 */ if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) { union display_idle_optimization_u idle_info = { 0 }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c @@ -99,20 +99,25 @@ return display_count; } -static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) +static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, + bool safe_to_lower, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = safe_to_lower + ? &context->res_ctx.pipe_ctx[i] + : &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; - if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL || - dc_is_virtual_signal(pipe->stream->signal))) { + if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) || + !pipe->stream->link_enc)) { if (disable) { - pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); + if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc) + pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); + reset_sync_context_for_pipe(dc, context, i); } else pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); @@ -207,11 +212,11 @@ } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn316_disable_otg_wa(clk_mgr_base, context, true); + dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn316_disable_otg_wa(clk_mgr_base, context, false); + dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false); update_dispclk = true; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -216,6 +216,16 @@ if (clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz > 1950) clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = 1950; + /* DPPCLK */ + dcn32_init_single_clock(clk_mgr, PPCLK_DPPCLK, + &clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz, + &num_entries_per_clk->num_dppclk_levels); + num_levels = num_entries_per_clk->num_dppclk_levels; + clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DPPCLK); + //HW recommends limit of 1950 MHz in display clock for all DCN3.2.x + if (clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz > 1950) + clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz = 1950; + if (num_entries_per_clk->num_dcfclk_levels && num_entries_per_clk->num_dtbclk_levels && num_entries_per_clk->num_dispclk_levels) @@ -240,6 +250,10 @@ = khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz); } + for (i = 0; i < num_levels; i++) + if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz > 1950) + clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz = 1950; + /* Get UCLK, update bounding box */ clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base); @@ -682,8 +696,12 @@ * since we calculate mode support based on softmax being the max UCLK * frequency. */ - dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, - dc->clk_mgr->bw_params->dc_mode_softmax_memclk); + if (dc->debug.disable_dc_mode_overwrite) { + dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz); + dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz); + } else + dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, + dc->clk_mgr->bw_params->dc_mode_softmax_memclk); } else { dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz); } @@ -716,8 +734,13 @@ /* set UCLK to requested value if P-State switching is supported, or to re-enable P-State switching */ if (clk_mgr_base->clks.p_state_change_support && (update_uclk || !clk_mgr_base->clks.prev_p_state_change_support) && - !dc->work_arounds.clock_update_disable_mask.uclk) + !dc->work_arounds.clock_update_disable_mask.uclk) { + if (dc->clk_mgr->dc_mode_softmax_enabled && dc->debug.disable_dc_mode_overwrite) + dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, + max((int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz))); + dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz)); + } if (clk_mgr_base->clks.num_ways != new_clocks->num_ways && clk_mgr_base->clks.num_ways > new_clocks->num_ways) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -384,19 +384,6 @@ dcn35_smu_enable_pme_wa(clk_mgr); } -void dcn35_init_clocks(struct clk_mgr *clk_mgr) -{ - uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz; - - memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); - - // Assumption is that boot state always supports pstate - clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk - clk_mgr->clks.p_state_change_support = true; - clk_mgr->clks.prev_p_state_change_support = true; - clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; - clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN; -} bool dcn35_are_clock_states_equal(struct dc_clocks *a, struct dc_clocks *b) @@ -421,7 +408,19 @@ struct clk_mgr_dcn35 *clk_mgr) { } +void dcn35_init_clocks(struct clk_mgr *clk_mgr) +{ + uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz; + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); + + // Assumption is that boot state always supports pstate + clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk + clk_mgr->clks.p_state_change_support = true; + clk_mgr->clks.prev_p_state_change_support = true; + clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; + clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN; +} static struct clk_bw_params dcn35_bw_params = { .vram_type = Ddr4MemType, .num_channels = 1, @@ -706,7 +705,7 @@ clock_table->NumFclkLevelsEnabled; max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, num_fclk); - num_dcfclk = (clock_table->NumFclkLevelsEnabled > NUM_DCFCLK_DPM_LEVELS) ? NUM_DCFCLK_DPM_LEVELS : + num_dcfclk = (clock_table->NumDcfClkLevelsEnabled > NUM_DCFCLK_DPM_LEVELS) ? NUM_DCFCLK_DPM_LEVELS : clock_table->NumDcfClkLevelsEnabled; for (i = 0; i < num_dcfclk; i++) { int j; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -411,9 +411,14 @@ * avoid conflicting with firmware updates. */ if (dc->ctx->dce_version > DCE_VERSION_MAX) - if (dc->optimized_required || dc->wm_optimized_required) + if (dc->optimized_required) return false; + if (!memcmp(&stream->adjust, adjust, sizeof(*adjust))) + return true; + + dc_exit_ips_for_hw_access(dc); + stream->adjust.v_total_max = adjust->v_total_max; stream->adjust.v_total_mid = adjust->v_total_mid; stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num; @@ -454,6 +459,8 @@ int i = 0; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; @@ -484,6 +491,8 @@ bool ret = false; struct crtc_position position; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; @@ -603,6 +612,8 @@ if (pipe == NULL) return false; + dc_exit_ips_for_hw_access(dc); + /* By default, capture the full frame */ param.windowa_x_start = 0; param.windowa_y_start = 0; @@ -662,6 +673,8 @@ struct pipe_ctx *pipe; struct timing_generator *tg; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->stream == stream) @@ -686,6 +699,8 @@ int i; struct pipe_ctx *pipe_ctx; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) { @@ -721,6 +736,8 @@ if (option > DITHER_OPTION_MAX) return; + dc_exit_ips_for_hw_access(stream->ctx->dc); + stream->dither_option = option; memset(¶ms, 0, sizeof(params)); @@ -745,6 +762,8 @@ bool ret = false; struct pipe_ctx *pipes; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) { pipes = &dc->current_state->res_ctx.pipe_ctx[i]; @@ -762,6 +781,8 @@ bool ret = false; struct pipe_ctx *pipes; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) { @@ -788,6 +809,8 @@ struct pipe_ctx *pipes_affected[MAX_PIPES]; int num_pipes_affected = 0; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < num_streams; i++) { struct dc_stream_state *stream = streams[i]; @@ -1282,6 +1305,54 @@ } } +/** + * wait_for_blank_complete - wait for all active OPPs to finish pending blank + * pattern updates + * + * @dc: [in] dc reference + * @context: [in] hardware context in use + */ +static void wait_for_blank_complete(struct dc *dc, + struct dc_state *context) +{ + struct pipe_ctx *opp_head; + struct dce_hwseq *hws = dc->hwseq; + int i; + + if (!hws->funcs.wait_for_blank_complete) + return; + + for (i = 0; i < MAX_PIPES; i++) { + opp_head = &context->res_ctx.pipe_ctx[i]; + + if (!resource_is_pipe_type(opp_head, OPP_HEAD) || + dc_state_get_pipe_subvp_type(context, opp_head) == SUBVP_PHANTOM) + continue; + + hws->funcs.wait_for_blank_complete(opp_head->stream_res.opp); + } +} + +static void wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *context) +{ + struct pipe_ctx *otg_master; + struct timing_generator *tg; + int i; + + for (i = 0; i < MAX_PIPES; i++) { + otg_master = &context->res_ctx.pipe_ctx[i]; + if (!resource_is_pipe_type(otg_master, OTG_MASTER) || + dc_state_get_pipe_subvp_type(context, otg_master) == SUBVP_PHANTOM) + continue; + tg = otg_master->stream_res.tg; + if (tg->funcs->wait_odm_doublebuffer_pending_clear) + tg->funcs->wait_odm_doublebuffer_pending_clear(tg); + } + + /* ODM update may require to reprogram blank pattern for each OPP */ + wait_for_blank_complete(dc, context); +} + static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context) { int i; @@ -1733,6 +1804,9 @@ return false; } + if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) + return false; + if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) { DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n"); return false; @@ -1766,6 +1840,8 @@ int i, j; struct pipe_ctx *pipe; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { if (context != NULL) { pipe = &context->res_ctx.pipe_ctx[i]; @@ -1785,6 +1861,8 @@ void dc_trigger_sync(struct dc *dc, struct dc_state *context) { if (context->stream_count > 1 && !dc->debug.disable_timing_sync) { + dc_exit_ips_for_hw_access(dc); + enable_timing_multisync(dc, context); program_timing_sync(dc, context); } @@ -1969,6 +2047,11 @@ context->stream_count == 0) { /* Must wait for no flips to be pending before doing optimize bw */ wait_for_no_pipes_pending(dc, context); + /* + * optimized dispclk depends on ODM setup. Need to wait for ODM + * update pending complete before optimizing bandwidth. + */ + wait_for_odm_update_pending_complete(dc, context); /* pplib is notified if disp_num changed */ dc->hwss.optimize_bandwidth(dc, context); /* Need to do otg sync again as otg could be out of sync due to otg @@ -2041,6 +2124,8 @@ if (!streams_changed(dc, streams, stream_count)) return res; + dc_exit_ips_for_hw_access(dc); + DC_LOG_DC("%s: %d streams\n", __func__, stream_count); for (i = 0; i < stream_count; i++) { @@ -2227,7 +2312,6 @@ } dc->optimized_required = false; - dc->wm_optimized_required = false; } bool dc_set_generic_gpio_for_stereo(bool enable, @@ -2650,8 +2734,6 @@ } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) { dc->optimized_required = true; } - - dc->optimized_required |= dc->wm_optimized_required; } return type; @@ -2859,9 +2941,6 @@ if (update->vrr_active_fixed) stream->vrr_active_fixed = *update->vrr_active_fixed; - if (update->crtc_timing_adjust) - stream->adjust = *update->crtc_timing_adjust; - if (update->dpms_off) stream->dpms_off = *update->dpms_off; @@ -3223,6 +3302,9 @@ if (stream->link->replay_settings.config.replay_supported) return true; + if (stream->ctx->dce_version >= DCN_VERSION_3_5 && stream->abm_level) + return true; + return false; } @@ -3376,6 +3458,8 @@ int i, j; struct pipe_ctx *top_pipe_to_program = NULL; struct dc_stream_status *stream_status = NULL; + dc_exit_ips_for_hw_access(dc); + dc_z10_restore(dc); top_pipe_to_program = resource_get_otg_master_for_stream( @@ -3444,7 +3528,7 @@ top_pipe_to_program->stream->update_flags.raw = 0; } -static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state *dc_context) +static void wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context) { /* * This function calls HWSS to wait for any potentially double buffered @@ -3482,6 +3566,7 @@ } } } + wait_for_odm_update_pending_complete(dc, dc_context); } static void commit_planes_for_stream(struct dc *dc, @@ -3503,6 +3588,8 @@ // dc->current_state anymore, so we have to cache it before we apply // the new SubVP context subvp_prev_use = false; + dc_exit_ips_for_hw_access(dc); + dc_z10_restore(dc); if (update_type == UPDATE_TYPE_FULL) wait_for_outstanding_hw_updates(dc, context); @@ -4293,8 +4380,7 @@ stream_update->mst_bw_update || stream_update->func_shaper || stream_update->lut3d_func || - stream_update->pending_test_pattern || - stream_update->crtc_timing_adjust)) + stream_update->pending_test_pattern)) return true; if (stream) { @@ -4384,6 +4470,8 @@ bool is_plane_addition = 0; bool is_fast_update_only; + dc_exit_ips_for_hw_access(dc); + populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); is_fast_update_only = fast_update_only(dc, fast_update, srf_updates, surface_count, stream_update, stream); @@ -4504,6 +4592,8 @@ int i, j; struct dc_fast_update fast_update[MAX_SURFACES] = {0}; + dc_exit_ips_for_hw_access(dc); + populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); stream_status = dc_stream_get_status(stream); context = dc->current_state; @@ -4688,6 +4778,8 @@ case DC_ACPI_CM_POWER_STATE_D0: dc_state_construct(dc, dc->current_state); + dc_exit_ips_for_hw_access(dc); + dc_z10_restore(dc); dc->hwss.init_hw(dc); @@ -4829,24 +4921,24 @@ dc->idle_optimizations_allowed = allow; } -bool dc_dmub_is_ips_idle_state(struct dc *dc) +void dc_exit_ips_for_hw_access(struct dc *dc) { - uint32_t idle_state = 0; + if (dc->caps.ips_support) + dc_allow_idle_optimizations(dc, false); +} +bool dc_dmub_is_ips_idle_state(struct dc *dc) +{ if (dc->debug.disable_idle_power_optimizations) return false; if (!dc->caps.ips_support || (dc->config.disable_ips == DMUB_IPS_DISABLE_ALL)) return false; - if (dc->hwss.get_idle_state) - idle_state = dc->hwss.get_idle_state(dc); - - if (!(idle_state & DMUB_IPS1_ALLOW_MASK) || - !(idle_state & DMUB_IPS2_ALLOW_MASK)) - return true; + if (!dc->ctx->dmub_srv) + return false; - return false; + return dc->ctx->dmub_srv->idle_allowed; } /* set min and max memory clock to lowest and highest DPM level, respectively */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2179,50 +2179,91 @@ } } -void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state) +static void resource_log_pipe_for_stream(struct dc *dc, struct dc_state *state, + struct pipe_ctx *otg_master, int stream_idx) { - struct pipe_ctx *otg_master; struct pipe_ctx *opp_heads[MAX_PIPES]; struct pipe_ctx *dpp_pipes[MAX_PIPES]; - int stream_idx, slice_idx, dpp_idx, plane_idx, slice_count, dpp_count; + int slice_idx, dpp_idx, plane_idx, slice_count, dpp_count; bool is_primary; DC_LOGGER_INIT(dc->ctx->logger); + slice_count = resource_get_opp_heads_for_otg_master(otg_master, + &state->res_ctx, opp_heads); + for (slice_idx = 0; slice_idx < slice_count; slice_idx++) { + plane_idx = -1; + if (opp_heads[slice_idx]->plane_state) { + dpp_count = resource_get_dpp_pipes_for_opp_head( + opp_heads[slice_idx], + &state->res_ctx, + dpp_pipes); + for (dpp_idx = 0; dpp_idx < dpp_count; dpp_idx++) { + is_primary = !dpp_pipes[dpp_idx]->top_pipe || + dpp_pipes[dpp_idx]->top_pipe->plane_state != dpp_pipes[dpp_idx]->plane_state; + if (is_primary) + plane_idx++; + resource_log_pipe(dc, dpp_pipes[dpp_idx], + stream_idx, slice_idx, + plane_idx, slice_count, + is_primary); + } + } else { + resource_log_pipe(dc, opp_heads[slice_idx], + stream_idx, slice_idx, plane_idx, + slice_count, true); + } + + } +} + +static int resource_stream_to_stream_idx(struct dc_state *state, + struct dc_stream_state *stream) +{ + int i, stream_idx = -1; + + for (i = 0; i < state->stream_count; i++) + if (state->streams[i] == stream) { + stream_idx = i; + break; + } + + /* never return negative array index */ + if (stream_idx == -1) { + ASSERT(0); + return 0; + } + + return stream_idx; +} + +void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state) +{ + struct pipe_ctx *otg_master; + int stream_idx, phantom_stream_idx; + DC_LOGGER_INIT(dc->ctx->logger); + DC_LOG_DC(" pipe topology update"); DC_LOG_DC(" ________________________"); for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) { + if (state->streams[stream_idx]->is_phantom) + continue; + otg_master = resource_get_otg_master_for_stream( &state->res_ctx, state->streams[stream_idx]); - if (!otg_master || otg_master->stream_res.tg == NULL) { - DC_LOG_DC("topology update: otg_master NULL stream_idx %d!\n", stream_idx); - return; - } - slice_count = resource_get_opp_heads_for_otg_master(otg_master, - &state->res_ctx, opp_heads); - for (slice_idx = 0; slice_idx < slice_count; slice_idx++) { - plane_idx = -1; - if (opp_heads[slice_idx]->plane_state) { - dpp_count = resource_get_dpp_pipes_for_opp_head( - opp_heads[slice_idx], - &state->res_ctx, - dpp_pipes); - for (dpp_idx = 0; dpp_idx < dpp_count; dpp_idx++) { - is_primary = !dpp_pipes[dpp_idx]->top_pipe || - dpp_pipes[dpp_idx]->top_pipe->plane_state != dpp_pipes[dpp_idx]->plane_state; - if (is_primary) - plane_idx++; - resource_log_pipe(dc, dpp_pipes[dpp_idx], - stream_idx, slice_idx, - plane_idx, slice_count, - is_primary); - } - } else { - resource_log_pipe(dc, opp_heads[slice_idx], - stream_idx, slice_idx, plane_idx, - slice_count, true); - } - + resource_log_pipe_for_stream(dc, state, otg_master, stream_idx); + } + if (state->phantom_stream_count > 0) { + DC_LOG_DC(" | (phantom pipes) |"); + for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) { + if (state->stream_status[stream_idx].mall_stream_config.type != SUBVP_MAIN) + continue; + + phantom_stream_idx = resource_stream_to_stream_idx(state, + state->stream_status[stream_idx].mall_stream_config.paired_stream); + otg_master = resource_get_otg_master_for_stream( + &state->res_ctx, state->streams[phantom_stream_idx]); + resource_log_pipe_for_stream(dc, state, otg_master, stream_idx); } } DC_LOG_DC(" |________________________|\n"); @@ -3128,6 +3169,9 @@ { int i, available_audio_count; + if (id == ENGINE_ID_UNKNOWN) + return NULL; + available_audio_count = pool->audio_count; for (i = 0; i < available_audio_count; i++) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_state.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_state.c @@ -334,7 +334,8 @@ void dc_state_release(struct dc_state *state) { - kref_put(&state->refcount, dc_state_free); + if (state != NULL) + kref_put(&state->refcount, dc_state_free); } /* * dc_state_add_stream() - Add a new dc_stream_state to a dc_state. @@ -435,6 +436,15 @@ goto out; } + if (stream_status->plane_count == 0 && dc->config.enable_windowed_mpo_odm) + /* ODM combine could prevent us from supporting more planes + * we will reset ODM slice count back to 1 when all planes have + * been removed to maximize the amount of planes supported when + * new planes are added. + */ + resource_update_pipes_for_stream_with_slice_count( + state, dc->current_state, dc->res_pool, stream, 1); + otg_master_pipe = resource_get_otg_master_for_stream( &state->res_ctx, stream); if (otg_master_pipe) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -423,6 +423,8 @@ return false; } + dc_exit_ips_for_hw_access(dc); + wb_info->dwb_params.out_transfer_func = stream->out_transfer_func; dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst]; @@ -493,6 +495,8 @@ return false; } + dc_exit_ips_for_hw_access(dc); + if (dwb->funcs->set_fc_enable) dwb->funcs->set_fc_enable(dwb, DWB_FRAME_CAPTURE_DISABLE); @@ -542,6 +546,8 @@ return false; } + dc_exit_ips_for_hw_access(dc); + /* disable writeback */ if (dc->hwss.disable_writeback) { struct dwbc *dwb = dc->res_pool->dwbc[dwb_pipe_inst]; @@ -557,6 +563,8 @@ int num_dwb, struct dc_writeback_info *wb_info) { + dc_exit_ips_for_hw_access(dc); + if (dc->hwss.mmhubbub_warmup) return dc->hwss.mmhubbub_warmup(dc, num_dwb, wb_info); else @@ -569,6 +577,8 @@ struct resource_context *res_ctx = &dc->current_state->res_ctx; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; @@ -597,6 +607,8 @@ dc = stream->ctx->dc; res_ctx = &dc->current_state->res_ctx; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i]; @@ -628,6 +640,8 @@ struct resource_context *res_ctx = &dc->current_state->res_ctx; + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < MAX_PIPES; i++) { struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; @@ -664,6 +678,8 @@ if (i == MAX_PIPES) return true; + dc_exit_ips_for_hw_access(dc); + return dc->hwss.dmdata_status_done(pipe); } @@ -698,6 +714,8 @@ pipe_ctx->stream->dmdata_address = attr->address; + dc_exit_ips_for_hw_access(dc); + dc->hwss.program_dmdata_engine(pipe_ctx); if (hubp->funcs->dmdata_set_attributes != NULL && --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -161,6 +161,8 @@ break; } + dc_exit_ips_for_hw_access(dc); + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dc.h @@ -987,6 +987,7 @@ bool psp_disabled_wa; unsigned int ips2_eval_delay_us; unsigned int ips2_entry_delay_us; + bool disable_dmub_reallow_idle; bool disable_timeout; bool disable_extblankadj; unsigned int static_screen_wait_frames; @@ -1037,7 +1038,6 @@ /* Require to optimize clocks and bandwidth for added/removed planes */ bool optimized_required; - bool wm_optimized_required; bool idle_optimizations_allowed; bool enable_c20_dtm_b0; @@ -2325,6 +2325,7 @@ struct dc_cursor_attributes *cursor_attr); void dc_allow_idle_optimizations(struct dc *dc, bool allow); +void dc_exit_ips_for_hw_access(struct dc *dc); bool dc_dmub_is_ips_idle_state(struct dc *dc); /* set min and max memory clock to lowest and highest DPM level, respectively */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -1320,16 +1320,27 @@ * Powering up the hardware requires notifying PMFW and DMCUB. * Clearing the driver idle allow requires a DMCUB command. * DMCUB commands requires the DMCUB to be powered up and restored. - * - * Exit out early to prevent an infinite loop of DMCUB commands - * triggering exit low power - use software state to track this. */ - dc_dmub_srv->idle_allowed = allow_idle; - if (!allow_idle) + if (!allow_idle) { dc_dmub_srv_exit_low_power_state(dc); - else + /* + * Idle is considered fully exited only after the sequence above + * fully completes. If we have a race of two threads exiting + * at the same time then it's safe to perform the sequence + * twice as long as we're not re-entering. + * + * Infinite command submission is avoided by using the + * dm_execute_dmub_cmd submission instead of the "wake" helpers. + */ + dc_dmub_srv->idle_allowed = false; + } else { + /* Consider idle as notified prior to the actual submission to + * prevent multiple entries. */ + dc_dmub_srv->idle_allowed = true; + dc_dmub_srv_notify_idle(dc, allow_idle); + } } bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd, @@ -1364,7 +1375,7 @@ else result = dm_execute_dmub_cmd(ctx, cmd, wait_type); - if (result && reallow_idle) + if (result && reallow_idle && !ctx->dc->debug.disable_dmub_reallow_idle) dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true); return result; @@ -1413,7 +1424,7 @@ result = dc_dmub_execute_gpint(ctx, command_code, param, response, wait_type); - if (result && reallow_idle) + if (result && reallow_idle && !ctx->dc->debug.disable_dmub_reallow_idle) dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true); return result; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -139,7 +139,6 @@ uint32_t wb_update:1; uint32_t dsc_changed : 1; uint32_t mst_bw : 1; - uint32_t crtc_timing_adjust : 1; uint32_t fams_changed : 1; } bits; @@ -326,7 +325,6 @@ struct dc_3dlut *lut3d_func; struct test_pattern *pending_test_pattern; - struct dc_crtc_timing_adjust *crtc_timing_adjust; }; bool dc_is_stream_unchanged( --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -1085,9 +1085,9 @@ /* SMU optimization is enabled */ bool replay_smu_opt_enable; /* Current Coasting vtotal */ - uint16_t coasting_vtotal; + uint32_t coasting_vtotal; /* Coasting vtotal table */ - uint16_t coasting_vtotal_table[PR_COASTING_TYPE_NUM]; + uint32_t coasting_vtotal_table[PR_COASTING_TYPE_NUM]; /* Maximum link off frame count */ enum replay_link_off_frame_count_level link_off_frame_count_level; /* Replay pseudo vtotal for abm + ips on full screen video which can improve ips residency */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce110/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dce110/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. -CFLAGS_$(AMDDALPATH)/dc/dce110/dce110_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce110/dce110_resource.o = -Wno-override-init DCE110 = dce110_timing_generator.o \ dce110_compressor.o dce110_opp_regamma_v.o \ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce112/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dce112/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. -CFLAGS_$(AMDDALPATH)/dc/dce112/dce112_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce112/dce112_resource.o = -Wno-override-init DCE112 = dce112_compressor.o --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce120/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dce120/Makefile @@ -24,7 +24,7 @@ # It provides the control and status of HW CRTC block. -CFLAGS_$(AMDDALPATH)/dc/dce120/dce120_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce120/dce120_resource.o = -Wno-override-init DCE120 = dce120_timing_generator.o --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce60/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dce60/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. -CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = -Wno-override-init DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \ dce60_resource.o --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce80/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dce80/Makefile @@ -23,7 +23,7 @@ # Makefile for the 'controller' sub-component of DAL. # It provides the control and status of HW CRTC block. -CFLAGS_$(AMDDALPATH)/dc/dce80/dce80_resource.o = $(call cc-disable-warning, override-init) +CFLAGS_$(AMDDALPATH)/dc/dce80/dce80_resource.o = -Wno-override-init DCE80 = dce80_timing_generator.o --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -382,6 +382,11 @@ i += increment) { if (j == hw_points - 1) break; + if (i >= TRANSFER_FUNC_POINTS) { + DC_LOG_ERROR("Index out of bounds: i=%d, TRANSFER_FUNC_POINTS=%d\n", + i, TRANSFER_FUNC_POINTS); + return false; + } rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c @@ -377,6 +377,7 @@ .opp_set_disp_pattern_generator = NULL, .opp_program_dpg_dimensions = NULL, .dpg_is_blanked = NULL, + .dpg_is_pending = NULL, .opp_destroy = opp1_destroy }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c @@ -337,6 +337,19 @@ (double_buffer_pending == 0); } +bool opp2_dpg_is_pending(struct output_pixel_processor *opp) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + uint32_t double_buffer_pending; + uint32_t dpg_en; + + REG_GET(DPG_CONTROL, DPG_EN, &dpg_en); + + REG_GET(DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending); + + return (dpg_en == 1 && double_buffer_pending == 1); +} + void opp2_program_left_edge_extra_pixel ( struct output_pixel_processor *opp, bool count) @@ -363,6 +376,7 @@ .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, .dpg_is_blanked = opp2_dpg_is_blanked, + .dpg_is_pending = opp2_dpg_is_pending, .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, .opp_destroy = opp1_destroy, .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h @@ -159,6 +159,8 @@ bool opp2_dpg_is_blanked(struct output_pixel_processor *opp); +bool opp2_dpg_is_pending(struct output_pixel_processor *opp); + void opp2_dpg_set_blank_color( struct output_pixel_processor *opp, const struct tg_color *color); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c @@ -50,6 +50,7 @@ .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, .dpg_is_blanked = opp2_dpg_is_blanked, + .dpg_is_pending = opp2_dpg_is_pending, .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, .opp_destroy = opp1_destroy, .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c @@ -44,6 +44,36 @@ #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) +void mpc3_mpc_init(struct mpc *mpc) +{ + struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); + int opp_id; + + mpc1_mpc_init(mpc); + + for (opp_id = 0; opp_id < MAX_OPP; opp_id++) { + if (REG(MUX[opp_id])) + /* disable mpc out rate and flow control */ + REG_UPDATE_2(MUX[opp_id], MPC_OUT_RATE_CONTROL_DISABLE, + 1, MPC_OUT_FLOW_CONTROL_COUNT, 0); + } +} + +void mpc3_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id) +{ + struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); + + mpc1_mpc_init_single_inst(mpc, mpcc_id); + + /* assuming mpc out mux is connected to opp with the same index at this + * point in time (e.g. transitioning from vbios to driver) + */ + if (mpcc_id < MAX_OPP && REG(MUX[mpcc_id])) + /* disable mpc out rate and flow control */ + REG_UPDATE_2(MUX[mpcc_id], MPC_OUT_RATE_CONTROL_DISABLE, + 1, MPC_OUT_FLOW_CONTROL_COUNT, 0); +} + bool mpc3_is_dwb_idle( struct mpc *mpc, int dwb_id) @@ -80,25 +110,6 @@ MPC_DWB0_MUX, 0xf); } -void mpc3_set_out_rate_control( - struct mpc *mpc, - int opp_id, - bool enable, - bool rate_2x_mode, - struct mpc_dwb_flow_control *flow_control) -{ - struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); - - REG_UPDATE_2(MUX[opp_id], - MPC_OUT_RATE_CONTROL_DISABLE, !enable, - MPC_OUT_RATE_CONTROL, rate_2x_mode); - - if (flow_control) - REG_UPDATE_2(MUX[opp_id], - MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode, - MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1); -} - enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id) { /*Contrary to DCN2 and DCN1 wherein a single status register field holds this info; @@ -1386,8 +1397,8 @@ .read_mpcc_state = mpc1_read_mpcc_state, .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, - .mpc_init = mpc1_mpc_init, - .mpc_init_single_inst = mpc1_mpc_init_single_inst, + .mpc_init = mpc3_mpc_init, + .mpc_init_single_inst = mpc3_mpc_init_single_inst, .update_blending = mpc2_update_blending, .cursor_lock = mpc1_cursor_lock, .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, @@ -1404,7 +1415,6 @@ .set_dwb_mux = mpc3_set_dwb_mux, .disable_dwb_mux = mpc3_disable_dwb_mux, .is_dwb_idle = mpc3_is_dwb_idle, - .set_out_rate_control = mpc3_set_out_rate_control, .set_gamut_remap = mpc3_set_gamut_remap, .program_shaper = mpc3_program_shaper, .acquire_rmu = mpcc3_acquire_rmu, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h @@ -1007,6 +1007,13 @@ int num_mpcc, int num_rmu); +void mpc3_mpc_init( + struct mpc *mpc); + +void mpc3_mpc_init_single_inst( + struct mpc *mpc, + unsigned int mpcc_id); + bool mpc3_program_shaper( struct mpc *mpc, const struct pwl_params *params, @@ -1074,13 +1081,6 @@ struct mpc *mpc, int dwb_id); -void mpc3_set_out_rate_control( - struct mpc *mpc, - int opp_id, - bool enable, - bool rate_2x_mode, - struct mpc_dwb_flow_control *flow_control); - void mpc3_power_on_ogam_lut( struct mpc *mpc, int mpcc_id, bool power_on); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c @@ -395,6 +395,12 @@ x), 25)); + // If y rounds up to integer, carry it over to x. + if (y >> 25) { + x += 1; + y = 0; + } + switch (stream_encoder_inst) { case 0: REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c @@ -34,6 +34,7 @@ #include "dc_bios_types.h" #include "link_enc_cfg.h" +#include "dc_dmub_srv.h" #include "gpio_service_interface.h" #ifndef MIN @@ -61,6 +62,38 @@ #define AUX_REG_WRITE(reg_name, val) \ dm_write_reg(CTX, AUX_REG(reg_name), val) +static uint8_t phy_id_from_transmitter(enum transmitter t) +{ + uint8_t phy_id; + + switch (t) { + case TRANSMITTER_UNIPHY_A: + phy_id = 0; + break; + case TRANSMITTER_UNIPHY_B: + phy_id = 1; + break; + case TRANSMITTER_UNIPHY_C: + phy_id = 2; + break; + case TRANSMITTER_UNIPHY_D: + phy_id = 3; + break; + case TRANSMITTER_UNIPHY_E: + phy_id = 4; + break; + case TRANSMITTER_UNIPHY_F: + phy_id = 5; + break; + case TRANSMITTER_UNIPHY_G: + phy_id = 6; + break; + default: + phy_id = 0; + break; + } + return phy_id; +} void enc32_hw_init(struct link_encoder *enc) { @@ -117,38 +150,50 @@ } } -static bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc) +static bool query_dp_alt_from_dmub(struct link_encoder *enc, + union dmub_rb_cmd *cmd) { struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - uint32_t dp_alt_mode_disable = 0; - bool is_usb_c_alt_mode = false; - if (enc->features.flags.bits.DP_IS_USB_C) { - /* if value == 1 alt mode is disabled, otherwise it is enabled */ - REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); - is_usb_c_alt_mode = (dp_alt_mode_disable == 0); - } + memset(cmd, 0, sizeof(*cmd)); + cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS; + cmd->query_dp_alt.header.sub_type = + DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT; + cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data); + cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter); - return is_usb_c_alt_mode; + if (!dc_wake_and_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) + return false; + + return true; } -static void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc, +bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc) +{ + union dmub_rb_cmd cmd; + + if (!query_dp_alt_from_dmub(enc, &cmd)) + return false; + + return (cmd.query_dp_alt.data.is_dp_alt_disable == 0); +} + +void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc, struct dc_link_settings *link_settings) { - struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); - uint32_t is_in_usb_c_dp4_mode = 0; + union dmub_rb_cmd cmd; dcn10_link_encoder_get_max_link_cap(enc, link_settings); - /* in usb c dp2 mode, max lane count is 2 */ - if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) { - REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode); - if (!is_in_usb_c_dp4_mode) - link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); - } + if (!query_dp_alt_from_dmub(enc, &cmd)) + return; + if (cmd.query_dp_alt.data.is_usb && + cmd.query_dp_alt.data.is_dp4 == 0) + link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count); } + static const struct link_encoder_funcs dcn32_link_enc_funcs = { .read_state = link_enc2_read_state, .validate_output_with_stream = @@ -203,12 +248,12 @@ enc10->base.hpd_source = init_data->hpd_source; enc10->base.connector = init_data->connector; + if (enc10->base.connector.id == CONNECTOR_ID_USBC) + enc10->base.features.flags.bits.DP_IS_USB_C = 1; enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; enc10->base.features = *enc_features; - if (enc10->base.connector.id == CONNECTOR_ID_USBC) - enc10->base.features.flags.bits.DP_IS_USB_C = 1; enc10->base.transmitter = init_data->transmitter; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h @@ -53,4 +53,9 @@ const struct dc_link_settings *link_settings, enum clock_source_id clock_source); +bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc); + +void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc, + struct dc_link_settings *link_settings); + #endif /* __DC_LINK_ENCODER__DCN32_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c @@ -47,7 +47,7 @@ struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); int mpcc_id; - mpc1_mpc_init(mpc); + mpc3_mpc_init(mpc); if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { if (mpc30->mpc_mask->MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE) { @@ -991,7 +991,7 @@ .insert_plane = mpc1_insert_plane, .remove_mpcc = mpc1_remove_mpcc, .mpc_init = mpc32_mpc_init, - .mpc_init_single_inst = mpc1_mpc_init_single_inst, + .mpc_init_single_inst = mpc3_mpc_init_single_inst, .update_blending = mpc2_update_blending, .cursor_lock = mpc1_cursor_lock, .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, @@ -1008,7 +1008,6 @@ .set_dwb_mux = mpc3_set_dwb_mux, .disable_dwb_mux = mpc3_disable_dwb_mux, .is_dwb_idle = mpc3_is_dwb_idle, - .set_out_rate_control = mpc3_set_out_rate_control, .set_gamut_remap = mpc3_set_gamut_remap, .program_shaper = mpc32_program_shaper, .program_3dlut = mpc32_program_3dlut, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c @@ -782,3 +782,9 @@ pipe_cnt++; } } + +void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context) +{ + if (dcn32_subvp_in_use(dc, context) && context->bw_ctx.bw.dcn.clk.dcfclk_khz <= MIN_SUBVP_DCFCLK_KHZ) + context->bw_ctx.bw.dcn.clk.dcfclk_khz = MIN_SUBVP_DCFCLK_KHZ; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c @@ -184,6 +184,8 @@ enc10->base.hpd_source = init_data->hpd_source; enc10->base.connector = init_data->connector; + if (enc10->base.connector.id == CONNECTOR_ID_USBC) + enc10->base.features.flags.bits.DP_IS_USB_C = 1; enc10->base.preferred_engine = ENGINE_ID_UNKNOWN; @@ -238,8 +240,6 @@ } enc10->base.features.flags.bits.HDMI_6GB_EN = 1; - if (enc10->base.connector.id == CONNECTOR_ID_USBC) - enc10->base.features.flags.bits.DP_IS_USB_C = 1; if (bp_funcs->get_connector_speed_cap_info) result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c @@ -291,6 +291,7 @@ .do_urgent_latency_adjustment = false, .urgent_latency_adjustment_fabric_clock_component_us = 0, .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, + .dispclk_dppclk_vco_speed_mhz = 2400.0, .num_chans = 4, .dummy_pstate_latency_us = 10.0 }; @@ -438,6 +439,7 @@ .do_urgent_latency_adjustment = false, .urgent_latency_adjustment_fabric_clock_component_us = 0, .urgent_latency_adjustment_fabric_clock_reference_mhz = 0, + .dispclk_dppclk_vco_speed_mhz = 2500.0, }; void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -2760,7 +2760,7 @@ struct _vcs_dpi_voltage_scaling_st entry = {0}; struct clk_limit_table_entry max_clk_data = {0}; - unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299; + unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599; static const unsigned int num_dcfclk_stas = 5; unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564}; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -3364,6 +3364,9 @@ &mode_lib->vba.UrgentBurstFactorLumaPre[k], &mode_lib->vba.UrgentBurstFactorChromaPre[k], &mode_lib->vba.NotUrgentLatencyHidingPre[k]); + + v->cursor_bw_pre[k] = mode_lib->vba.NumberOfCursors[k] * mode_lib->vba.CursorWidth[k][0] * mode_lib->vba.CursorBPP[k][0] / + 8.0 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * v->VRatioPreY[i][j][k]; } { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c @@ -177,7 +177,7 @@ .urgent_latency_pixel_data_only_us = 4.0, .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, .urgent_latency_vm_data_only_us = 4.0, - .dram_clock_change_latency_us = 11.72, + .dram_clock_change_latency_us = 34.0, .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c @@ -9460,8 +9460,10 @@ /* Copy the calculated watermarks to mp.Watermark as the getter functions are * implemented by the DML team to copy the calculated values from the mp.Watermark interface. + * &mode_lib->mp.Watermark and &locals->Watermark are the same address, memcpy may lead to + * unexpected behavior. memmove should be used. */ - memcpy(&mode_lib->mp.Watermark, CalculateWatermarks_params->Watermark, sizeof(struct Watermarks)); + memmove(&mode_lib->mp.Watermark, CalculateWatermarks_params->Watermark, sizeof(struct Watermarks)); for (k = 0; k < mode_lib->ms.num_active_planes; ++k) { if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c @@ -88,7 +88,8 @@ return i; } - return -1; + ASSERT(false); + return __DML2_WRAPPER_MAX_STREAMS_PLANES__; } static int find_disp_cfg_idx_by_stream_id(struct dml2_dml_to_dc_pipe_mapping *mapping, unsigned int stream_id) @@ -100,7 +101,8 @@ return i; } - return -1; + ASSERT(false); + return __DML2_WRAPPER_MAX_STREAMS_PLANES__; } // The master pipe of a stream is defined as the top pipe in odm slice 0 --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c @@ -228,17 +228,14 @@ break; case dml_project_dcn35: + case dml_project_dcn351: out->num_chans = 4; out->round_trip_ping_latency_dcfclk_cycles = 106; out->smn_latency_us = 2; out->dispclk_dppclk_vco_speed_mhz = 3600; + out->pct_ideal_dram_bw_after_urgent_pixel_only = 65.0; break; - case dml_project_dcn351: - out->num_chans = 16; - out->round_trip_ping_latency_dcfclk_cycles = 1100; - out->smn_latency_us = 2; - break; } /* ---Overrides if available--- */ if (dml2->config.bbox_overrides.dram_num_chan) @@ -824,13 +821,25 @@ static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_stream_state *in) { + dml_uint_t width, height; + + if (in->timing.h_addressable > 3840) + width = 3840; + else + width = in->timing.h_addressable; // 4K max + + if (in->timing.v_addressable > 2160) + height = 2160; + else + height = in->timing.v_addressable; // 4K max + out->CursorBPP[location] = dml_cur_32bit; out->CursorWidth[location] = 256; out->GPUVMMinPageSizeKBytes[location] = 256; - out->ViewportWidth[location] = in->timing.h_addressable; - out->ViewportHeight[location] = in->timing.v_addressable; + out->ViewportWidth[location] = width; + out->ViewportHeight[location] = height; out->ViewportStationary[location] = false; out->ViewportWidthChroma[location] = 0; out->ViewportHeightChroma[location] = 0; @@ -849,7 +858,7 @@ out->HTapsChroma[location] = 0; out->VTapsChroma[location] = 0; out->SourceScan[location] = dml_rotation_0; - out->ScalerRecoutWidth[location] = in->timing.h_addressable; + out->ScalerRecoutWidth[location] = width; out->LBBitPerPixel[location] = 57; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c @@ -294,7 +294,7 @@ context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = (unsigned int)in_ctx->v20.dml_core_ctx.mp.DCFCLKDeepSleep * 1000; context->bw_ctx.bw.dcn.clk.dppclk_khz = 0; - if (in_ctx->v20.dml_core_ctx.ms.support.FCLKChangeSupport[in_ctx->v20.scratch.mode_support_params.out_lowest_state_idx] == dml_fclock_change_unsupported) + if (in_ctx->v20.dml_core_ctx.ms.support.FCLKChangeSupport[0] == dml_fclock_change_unsupported) context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = false; else context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = true; @@ -327,6 +327,8 @@ dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id); } + if (dml_pipe_idx == 0xFFFFFFFF) + continue; ASSERT(in_ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[dml_pipe_idx]); ASSERT(in_ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id[dml_pipe_idx] == context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id); @@ -468,6 +470,9 @@ dml_pipe_idx = find_dml_pipe_idx_by_plane_id(in_ctx, plane_id); else dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, display_state->res_ctx.pipe_ctx[i].stream->stream_id); + + if (dml_pipe_idx == 0xFFFFFFFF) + continue; total_det_allocated += dml_get_det_buffer_size_kbytes(&in_ctx->v20.dml_core_ctx, dml_pipe_idx); if (total_det_allocated > max_det_size) { need_recalculation = true; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c @@ -703,13 +703,8 @@ return (struct dml2_context *) kzalloc(sizeof(struct dml2_context), GFP_KERNEL); } -bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2) +static void dml2_init(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2) { - // Allocate Mode Lib Ctx - *dml2 = dml2_allocate_memory(); - - if (!(*dml2)) - return false; // Store config options (*dml2)->config = *config; @@ -737,9 +732,18 @@ initialize_dml2_soc_bbox(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc); initialize_dml2_soc_states(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc, &(*dml2)->v20.dml_core_ctx.states); +} + +bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2) +{ + // Allocate Mode Lib Ctx + *dml2 = dml2_allocate_memory(); + + if (!(*dml2)) + return false; + + dml2_init(in_dc, config, dml2); - /*Initialize DML20 instance which calls dml2_core_create, and core_dcn3_populate_informative*/ - //dml2_initialize_instance(&(*dml_ctx)->v20.dml_init); return true; } @@ -779,3 +783,11 @@ return true; } + +void dml2_reinit(const struct dc *in_dc, + const struct dml2_configuration_options *config, + struct dml2_context **dml2) +{ + + dml2_init(in_dc, config, dml2); +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h @@ -214,6 +214,9 @@ struct dml2_context *src_dml2); bool dml2_create_copy(struct dml2_context **dst_dml2, struct dml2_context *src_dml2); +void dml2_reinit(const struct dc *in_dc, + const struct dml2_configuration_options *config, + struct dml2_context **dml2); /* * dml2_validate - Determines if a display configuration is supported or not. --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -1050,7 +1050,12 @@ if (!is_dsc_possible) goto done; - dsc_cfg->num_slices_v = pic_height/slice_height; + if (slice_height > 0) { + dsc_cfg->num_slices_v = pic_height / slice_height; + } else { + is_dsc_possible = false; + goto done; + } if (target_bandwidth_kbps > 0) { is_dsc_possible = decide_dsc_target_bpp_x16( --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -1185,7 +1185,8 @@ if (dccg) { dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); - dccg->funcs->set_dtbclk_dto(dccg, &dto_params); + if (dccg && dccg->funcs->set_dtbclk_dto) + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); } } else if (dccg && dccg->funcs->disable_symclk_se) { dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -1840,6 +1840,9 @@ { struct dpp *dpp = pipe_ctx->plane_res.dpp; + if (!stream) + return false; + if (dpp == NULL) return false; @@ -1862,8 +1865,8 @@ } else dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS); - if (stream != NULL && stream->ctx != NULL && - stream->out_transfer_func != NULL) { + if (stream->ctx && + stream->out_transfer_func) { log_tf(stream->ctx, stream->out_transfer_func, dpp->regamma_params.hw_points_num); @@ -3076,7 +3079,7 @@ context, false); - dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub, + dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -1392,6 +1392,11 @@ return; } + if (resource_is_pipe_type(new_pipe, OTG_MASTER) && + resource_is_odm_topology_changed(new_pipe, old_pipe)) + /* Detect odm changes */ + new_pipe->update_flags.bits.odm = 1; + /* Exit on unchanged, unused pipe */ if (!old_pipe->plane_state && !new_pipe->plane_state) return; @@ -1445,10 +1450,6 @@ /* Detect top pipe only changes */ if (resource_is_pipe_type(new_pipe, OTG_MASTER)) { - /* Detect odm changes */ - if (resource_is_odm_topology_changed(new_pipe, old_pipe)) - new_pipe->update_flags.bits.odm = 1; - /* Detect global sync changes */ if (old_pipe->pipe_dlg_param.vready_offset != new_pipe->pipe_dlg_param.vready_offset || old_pipe->pipe_dlg_param.vstartup_start != new_pipe->pipe_dlg_param.vstartup_start @@ -1891,19 +1892,20 @@ DC_LOGGER_INIT(dc->ctx->logger); unsigned int prev_hubp_count = 0; unsigned int hubp_count = 0; + struct pipe_ctx *pipe; if (resource_is_pipe_topology_changed(dc->current_state, context)) resource_log_pipe_topology_update(dc, context); if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) { for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; + pipe = &context->res_ctx.pipe_ctx[i]; - if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->plane_state) { - ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); + if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->plane_state) { + ASSERT(!pipe->plane_state->triplebuffer_flips); /*turn off triple buffer for full update*/ dc->hwss.program_triplebuffer( - dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); + dc, pipe, pipe->plane_state->triplebuffer_flips); } } } @@ -1978,12 +1980,22 @@ DC_LOG_DC("Reset mpcc for pipe %d\n", dc->current_state->res_ctx.pipe_ctx[i].pipe_idx); } + /* update ODM for blanked OTG master pipes */ + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe = &context->res_ctx.pipe_ctx[i]; + if (resource_is_pipe_type(pipe, OTG_MASTER) && + !resource_is_pipe_type(pipe, DPP_PIPE) && + pipe->update_flags.bits.odm && + hws->funcs.update_odm) + hws->funcs.update_odm(dc, context, pipe); + } + /* * Program all updated pipes, order matters for mpcc setup. Start with * top pipe and program all pipes that follow in order */ for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + pipe = &context->res_ctx.pipe_ctx[i]; if (pipe->plane_state && !pipe->top_pipe) { while (pipe) { @@ -2022,17 +2034,6 @@ context->stream_status[0].plane_count > 1) { pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp); } - - /* when dynamic ODM is active, pipes must be reconfigured when all planes are - * disabled, as some transitions will leave software and hardware state - * mismatched. - */ - if (dc->debug.enable_single_display_2to1_odm_policy && - pipe->stream && - pipe->update_flags.bits.disable && - !pipe->prev_odm_pipe && - hws->funcs.update_odm) - hws->funcs.update_odm(dc, context, pipe); } } @@ -2159,10 +2160,10 @@ } /* program dchubbub watermarks: - * For assigning wm_optimized_required, use |= operator since we don't want + * For assigning optimized_required, use |= operator since we don't want * to clear the value if the optimize has not happened yet */ - dc->wm_optimized_required |= hubbub->funcs->program_watermarks(hubbub, + dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, false); @@ -2175,10 +2176,10 @@ if (hubbub->funcs->program_compbuf_size) { if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) { compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes; - dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes); + dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes); } else { compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb; - dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb); + dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb); } hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false); @@ -2344,7 +2345,7 @@ int counter; for (counter = 0; counter < 1000; counter++) { - if (opp->funcs->dpg_is_blanked(opp)) + if (!opp->funcs->dpg_is_pending(opp)) break; udelay(100); @@ -2355,7 +2356,7 @@ return false; } - return true; + return opp->funcs->dpg_is_blanked(opp); } bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c @@ -663,10 +663,20 @@ if (pipe_ctx == NULL) return; - if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL) + if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL) { pipe_ctx->stream_res.stream_enc->funcs->set_avmute( pipe_ctx->stream_res.stream_enc, enable); + + /* Wait for two frame to make sure AV mute is sent out */ + if (enable) { + pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); + pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); + pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); + pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK); + pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE); + } + } } void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c @@ -69,29 +69,6 @@ #define FN(reg_name, field_name) \ hws->shifts->field_name, hws->masks->field_name -static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, - int opp_cnt) -{ - bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing); - int flow_ctrl_cnt; - - if (opp_cnt >= 2) - hblank_halved = true; - - flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable - - stream->timing.h_border_left - - stream->timing.h_border_right; - - if (hblank_halved) - flow_ctrl_cnt /= 2; - - /* ODM combine 4:1 case */ - if (opp_cnt == 4) - flow_ctrl_cnt /= 2; - - return flow_ctrl_cnt; -} - static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) { struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; @@ -183,10 +160,6 @@ struct pipe_ctx *odm_pipe; int opp_cnt = 0; int opp_inst[MAX_PIPES] = {0}; - bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing)); - struct mpc_dwb_flow_control flow_control; - struct mpc *mpc = dc->res_pool->mpc; - int i; opp_cnt = get_odm_config(pipe_ctx, opp_inst); @@ -199,20 +172,6 @@ pipe_ctx->stream_res.tg->funcs->set_odm_bypass( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); - rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; - flow_control.flow_ctrl_mode = 0; - flow_control.flow_ctrl_cnt0 = 0x80; - flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt); - if (mpc->funcs->set_out_rate_control) { - for (i = 0; i < opp_cnt; ++i) { - mpc->funcs->set_out_rate_control( - mpc, opp_inst[i], - true, - rate_control_2x_pclk, - &flow_control); - } - } - for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( odm_pipe->stream_res.opp, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -966,29 +966,6 @@ } } -static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, - int opp_cnt) -{ - bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing); - int flow_ctrl_cnt; - - if (opp_cnt >= 2) - hblank_halved = true; - - flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable - - stream->timing.h_border_left - - stream->timing.h_border_right; - - if (hblank_halved) - flow_ctrl_cnt /= 2; - - /* ODM combine 4:1 case */ - if (opp_cnt == 4) - flow_ctrl_cnt /= 2; - - return flow_ctrl_cnt; -} - static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) { struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; @@ -1103,10 +1080,6 @@ struct pipe_ctx *odm_pipe; int opp_cnt = 0; int opp_inst[MAX_PIPES] = {0}; - bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing)); - struct mpc_dwb_flow_control flow_control; - struct mpc *mpc = dc->res_pool->mpc; - int i; opp_cnt = get_odm_config(pipe_ctx, opp_inst); @@ -1119,20 +1092,6 @@ pipe_ctx->stream_res.tg->funcs->set_odm_bypass( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); - rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; - flow_control.flow_ctrl_mode = 0; - flow_control.flow_ctrl_cnt0 = 0x80; - flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt); - if (mpc->funcs->set_out_rate_control) { - for (i = 0; i < opp_cnt; ++i) { - mpc->funcs->set_out_rate_control( - mpc, opp_inst[i], - true, - rate_control_2x_pclk, - &flow_control); - } - } - for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( odm_pipe->stream_res.opp, @@ -1156,6 +1115,13 @@ dsc->funcs->dsc_disconnect(dsc); } } + + if (!resource_is_pipe_type(pipe_ctx, DPP_PIPE)) + /* + * blank pattern is generated by OPP, reprogram blank pattern + * due to OPP count change + */ + dc->hwseq->funcs.blank_pixel_data(dc, pipe_ctx, true); } unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div) @@ -1778,3 +1744,26 @@ context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support; } } + +void dcn32_interdependent_update_lock(struct dc *dc, + struct dc_state *context, bool lock) +{ + unsigned int i; + struct pipe_ctx *pipe; + struct timing_generator *tg; + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe = &context->res_ctx.pipe_ctx[i]; + tg = pipe->stream_res.tg; + + if (!resource_is_pipe_type(pipe, OTG_MASTER) || + !tg->funcs->is_tg_enabled(tg) || + dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM) + continue; + + if (lock) + dc->hwss.pipe_control_lock(dc, pipe, true); + else + dc->hwss.pipe_control_lock(dc, pipe, false); + } +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h @@ -129,4 +129,6 @@ void dcn32_prepare_bandwidth(struct dc *dc, struct dc_state *context); +void dcn32_interdependent_update_lock(struct dc *dc, + struct dc_state *context, bool lock); #endif /* __DC_HWSS_DCN32_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c @@ -58,7 +58,7 @@ .disable_plane = dcn20_disable_plane, .disable_pixel_data = dcn20_disable_pixel_data, .pipe_control_lock = dcn20_pipe_control_lock, - .interdependent_update_lock = dcn10_lock_all_pipes, + .interdependent_update_lock = dcn32_interdependent_update_lock, .cursor_lock = dcn10_cursor_lock, .prepare_bandwidth = dcn32_prepare_bandwidth, .optimize_bandwidth = dcn20_optimize_bandwidth, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -358,29 +358,6 @@ } } -static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, - int opp_cnt) -{ - bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing); - int flow_ctrl_cnt; - - if (opp_cnt >= 2) - hblank_halved = true; - - flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable - - stream->timing.h_border_left - - stream->timing.h_border_right; - - if (hblank_halved) - flow_ctrl_cnt /= 2; - - /* ODM combine 4:1 case */ - if (opp_cnt == 4) - flow_ctrl_cnt /= 2; - - return flow_ctrl_cnt; -} - static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable) { struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; @@ -474,10 +451,6 @@ struct pipe_ctx *odm_pipe; int opp_cnt = 0; int opp_inst[MAX_PIPES] = {0}; - bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing)); - struct mpc_dwb_flow_control flow_control; - struct mpc *mpc = dc->res_pool->mpc; - int i; opp_cnt = get_odm_config(pipe_ctx, opp_inst); @@ -490,20 +463,6 @@ pipe_ctx->stream_res.tg->funcs->set_odm_bypass( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); - rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; - flow_control.flow_ctrl_mode = 0; - flow_control.flow_ctrl_cnt0 = 0x80; - flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt); - if (mpc->funcs->set_out_rate_control) { - for (i = 0; i < opp_cnt; ++i) { - mpc->funcs->set_out_rate_control( - mpc, opp_inst[i], - true, - rate_control_2x_pclk, - &flow_control); - } - } - for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( odm_pipe->stream_res.opp, @@ -679,22 +638,43 @@ bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable) { - struct dc_link *edp_links[MAX_NUM_EDP]; - int i, edp_num; if (dc->debug.dmcub_emulation) return true; if (enable) { - dc_get_edp_links(dc, edp_links, &edp_num); - if (edp_num == 0 || edp_num > 1) - return false; + uint32_t num_active_edp = 0; + int i; for (i = 0; i < dc->current_state->stream_count; ++i) { struct dc_stream_state *stream = dc->current_state->streams[i]; + struct dc_link *link = stream->link; + bool is_psr = link && !link->panel_config.psr.disable_psr && + (link->psr_settings.psr_version == DC_PSR_VERSION_1 || + link->psr_settings.psr_version == DC_PSR_VERSION_SU_1); + bool is_replay = link && link->replay_settings.replay_feature_enabled; + + /* Ignore streams that disabled. */ + if (stream->dpms_off) + continue; + + /* Active external displays block idle optimizations. */ + if (!dc_is_embedded_signal(stream->signal)) + return false; - if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal)) + /* If not PWRSEQ0 can't enter idle optimizations */ + if (link && link->link_index != 0) return false; + + /* Check for panel power features required for idle optimizations. */ + if (!is_psr && !is_replay) + return false; + + num_active_edp += 1; } + + /* If more than one active eDP then disallow. */ + if (num_active_edp > 1) + return false; } // TODO: review other cases when idle optimization is allowed @@ -1019,8 +999,7 @@ if (pipe_ctx->plane_res.dpp) update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->plane_res.hubp->inst] = false; - if ((pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp) && - pipe_ctx->plane_res.mpcc_inst >= 0) + if (pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp) update_state->pg_pipe_res_update[PG_MPCC][pipe_ctx->plane_res.mpcc_inst] = false; if (pipe_ctx->stream_res.dsc) @@ -1377,3 +1356,75 @@ } } } + +static bool should_avoid_empty_tu(struct pipe_ctx *pipe_ctx) +{ + /* Calculate average pixel count per TU, return false if under ~2.00 to + * avoid empty TUs. This is only required for DPIA tunneling as empty TUs + * are legal to generate for native DP links. Assume TU size 64 as there + * is currently no scenario where it's reprogrammed from HW default. + * MTPs have no such limitation, so this does not affect MST use cases. + */ + unsigned int pix_clk_mhz; + unsigned int symclk_mhz; + unsigned int avg_pix_per_tu_x1000; + unsigned int tu_size_bytes = 64; + struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; + struct dc_link_settings *link_settings = &pipe_ctx->link_config.dp_link_settings; + const struct dc *dc = pipe_ctx->stream->link->dc; + + if (pipe_ctx->stream->link->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) + return false; + + // Not necessary for MST configurations + if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) + return false; + + pix_clk_mhz = timing->pix_clk_100hz / 10000; + + // If this is true, can't block due to dynamic ODM + if (pix_clk_mhz > dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz) + return false; + + switch (link_settings->link_rate) { + case LINK_RATE_LOW: + symclk_mhz = 162; + break; + case LINK_RATE_HIGH: + symclk_mhz = 270; + break; + case LINK_RATE_HIGH2: + symclk_mhz = 540; + break; + case LINK_RATE_HIGH3: + symclk_mhz = 810; + break; + default: + // We shouldn't be tunneling any other rates, something is wrong + ASSERT(0); + return false; + } + + avg_pix_per_tu_x1000 = (1000 * pix_clk_mhz * tu_size_bytes) + / (symclk_mhz * link_settings->lane_count); + + // Add small empirically-decided margin to account for potential jitter + return (avg_pix_per_tu_x1000 < 2020); +} + +bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx) +{ + struct dc *dc = pipe_ctx->stream->ctx->dc; + + if (!is_h_timing_divisible_by_2(pipe_ctx->stream)) + return false; + + if (should_avoid_empty_tu(pipe_ctx)) + return false; + + if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && + dc->debug.enable_dp_dig_pixel_rate_div_policy) + return true; + + return false; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h @@ -90,4 +90,6 @@ void dcn35_set_drr(struct pipe_ctx **pipe_ctx, int num_pipes, struct dc_crtc_timing_adjust adjust); +bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx); + #endif /* __DC_HWSS_DCN35_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c @@ -158,7 +158,7 @@ .setup_hpo_hw_control = dcn35_setup_hpo_hw_control, .calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values, .set_pixels_per_cycle = dcn32_set_pixels_per_cycle, - .is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy, + .is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy, .dsc_pg_control = dcn35_dsc_pg_control, .dsc_pg_status = dcn32_dsc_pg_status, .enable_plane = dcn35_enable_plane, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h @@ -321,6 +321,9 @@ bool (*dpg_is_blanked)( struct output_pixel_processor *opp); + bool (*dpg_is_pending)(struct output_pixel_processor *opp); + + void (*opp_dpg_set_blank_color)( struct output_pixel_processor *opp, const struct tg_color *color); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -333,6 +333,7 @@ void (*init_odm)(struct timing_generator *tg); void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg); + void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator *tg); }; #endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/link.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/inc/link.h @@ -285,12 +285,12 @@ enum replay_FW_Message_type msg, union dmub_replay_cmd_set *cmd_data); bool (*edp_set_coasting_vtotal)( - struct dc_link *link, uint16_t coasting_vtotal); + struct dc_link *link, uint32_t coasting_vtotal); bool (*edp_replay_residency)(const struct dc_link *link, unsigned int *residency, const bool is_start, const bool is_alpm); bool (*edp_set_replay_power_opt_and_coasting_vtotal)(struct dc_link *link, - const unsigned int *power_opts, uint16_t coasting_vtotal); + const unsigned int *power_opts, uint32_t coasting_vtotal); bool (*edp_wait_for_t12)(struct dc_link *link); bool (*edp_is_ilr_optimization_required)(struct dc_link *link, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c @@ -211,8 +211,12 @@ info->ext_id); uint8_t pipe_offset = dal_irq_src - IRQ_TYPE_VBLANK; - struct timing_generator *tg = - dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; + struct timing_generator *tg; + + if (pipe_offset >= MAX_PIPES) + return false; + + tg = dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg; if (enable) { if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1590,9 +1590,17 @@ return false; } - if (dp_is_lttpr_present(link)) + if (dp_is_lttpr_present(link)) { configure_lttpr_mode_transparent(link); + // Echo TOTAL_LTTPR_CNT back downstream + core_link_write_dpcd( + link, + DP_TOTAL_LTTPR_CNT, + &link->dpcd_caps.lttpr_caps.phy_repeater_cnt, + sizeof(link->dpcd_caps.lttpr_caps.phy_repeater_cnt)); + } + /* Read DP tunneling information. */ status = dpcd_get_tunneling_device_data(link); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -270,7 +270,7 @@ /* Error check whether requested and allocated are equal */ req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - if (req_bw == link->dpia_bw_alloc_config.allocated_bw) { + if (req_bw && (req_bw == link->dpia_bw_alloc_config.allocated_bw)) { DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n", __func__, link->link_index); } @@ -341,6 +341,14 @@ ret = true; init_usb4_bw_struct(link); link->dpia_bw_alloc_config.bw_alloc_enabled = true; + + /* + * During DP tunnel creation, CM preallocates BW and reduces estimated BW of other + * DPIA. CM release preallocation only when allocation is complete. Do zero alloc + * to make the CM to release preallocation and update estimated BW correctly for + * all DPIAs per host router + */ + link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, 0); } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -892,7 +892,8 @@ /* Set power optimization flag */ if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) { - if (link->replay_settings.replay_feature_enabled && replay->funcs->replay_set_power_opt) { + if (replay != NULL && link->replay_settings.replay_feature_enabled && + replay->funcs->replay_set_power_opt) { replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst); link->replay_settings.replay_power_opt_active = *power_opts; } @@ -1033,7 +1034,7 @@ return true; } -bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal) +bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal) { struct dc *dc = link->ctx->dc; struct dmub_replay *replay = dc->res_pool->replay; @@ -1072,7 +1073,7 @@ } bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link, - const unsigned int *power_opts, uint16_t coasting_vtotal) + const unsigned int *power_opts, uint32_t coasting_vtotal) { struct dc *dc = link->ctx->dc; struct dmub_replay *replay = dc->res_pool->replay; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h @@ -59,12 +59,12 @@ bool edp_send_replay_cmd(struct dc_link *link, enum replay_FW_Message_type msg, union dmub_replay_cmd_set *cmd_data); -bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal); +bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal); bool edp_replay_residency(const struct dc_link *link, unsigned int *residency, const bool is_start, const bool is_alpm); bool edp_get_replay_state(const struct dc_link *link, uint64_t *state); bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link, - const unsigned int *power_opts, uint16_t coasting_vtotal); + const unsigned int *power_opts, uint32_t coasting_vtotal); bool edp_wait_for_t12(struct dc_link *link); bool edp_is_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timing *crtc_timing); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h @@ -557,7 +557,8 @@ type OTG_CRC_DATA_STREAM_SPLIT_MODE;\ type OTG_CRC_DATA_FORMAT;\ type OTG_V_TOTAL_LAST_USED_BY_DRR;\ - type OTG_DRR_TIMING_DBUF_UPDATE_PENDING; + type OTG_DRR_TIMING_DBUF_UPDATE_PENDING;\ + type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING; #define TG_REG_FIELD_LIST_DCN3_2(type) \ type OTG_H_TIMING_DIV_MODE_MANUAL; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c @@ -122,6 +122,13 @@ } } +void optc32_wait_odm_doublebuffer_pending_clear(struct timing_generator *tg) +{ + struct optc *optc1 = DCN10TG_FROM_TG(tg); + + REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL, OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING, 0, 2, 50000); +} + void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -260,9 +267,6 @@ OTG_V_TOTAL_MAX_SEL, 1, OTG_FORCE_LOCK_ON_EVENT, 0, OTG_SET_V_TOTAL_MIN_MASK, (1 << 1)); /* TRIGA */ - - // Setup manual flow control for EOF via TRIG_A - optc->funcs->setup_manual_trigger(optc); } } @@ -345,6 +349,7 @@ .set_odm_bypass = optc32_set_odm_bypass, .set_odm_combine = optc32_set_odm_combine, .get_odm_combine_segments = optc32_get_odm_combine_segments, + .wait_odm_doublebuffer_pending_clear = optc32_wait_odm_doublebuffer_pending_clear, .set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode, .get_optc_source = optc2_get_optc_source, .set_out_mux = optc3_set_out_mux, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h @@ -183,5 +183,6 @@ void optc32_get_odm_combine_segments(struct timing_generator *tg, int *odm_combine_segments); void optc32_set_odm_bypass(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing); +void optc32_wait_odm_doublebuffer_pending_clear(struct timing_generator *tg); #endif /* __DC_OPTC_DCN32_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c @@ -2451,6 +2451,7 @@ dc->caps.post_blend_color_processing = true; dc->caps.force_dp_tps4_for_cp2520 = true; dc->caps.extended_aux_timeout_support = true; + dc->caps.dmcub_support = true; /* Color pipeline capabilities */ dc->caps.color.dpp.dcn_arch = 1; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c @@ -892,7 +892,7 @@ .disable_z10 = true, .enable_legacy_fast_update = true, .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/ - .dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE, + .dml_hostvm_override = DML_HOSTVM_NO_OVERRIDE, .using_dml2 = false, }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c @@ -1771,6 +1771,7 @@ dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); dcn32_override_min_req_memclk(dc, context); + dcn32_override_min_req_dcfclk(dc, context); BW_VAL_TRACE_END_WATERMARKS(); @@ -1930,6 +1931,8 @@ { DC_FP_START(); dcn32_update_bw_bounding_box_fpu(dc, bw_params); + if (dc->debug.using_dml2 && dc->current_state && dc->current_state->bw_ctx.dml2) + dml2_reinit(dc, &dc->dml2_options, &dc->current_state->bw_ctx.dml2); DC_FP_END(); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h @@ -42,6 +42,7 @@ #define SUBVP_ACTIVE_MARGIN_LIST_LEN 2 #define DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ 1800 #define DCN3_2_VMIN_DISPCLK_HZ 717000000 +#define MIN_SUBVP_DCFCLK_KHZ 400000 #define TO_DCN32_RES_POOL(pool)\ container_of(pool, struct dcn32_resource_pool, base) @@ -181,6 +182,8 @@ void dcn32_update_dml_pipes_odm_policy_based_on_context(struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes); +void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context); + /* definitions for run time init of reg offsets */ /* CLK SRC */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c @@ -1581,6 +1581,8 @@ { DC_FP_START(); dcn321_update_bw_bounding_box_fpu(dc, bw_params); + if (dc->debug.using_dml2 && dc->current_state && dc->current_state->bw_ctx.dml2) + dml2_reinit(dc, &dc->dml2_options, &dc->current_state->bw_ctx.dml2); DC_FP_END(); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -701,7 +701,7 @@ // 6:1 downscaling ratio: 1000/6 = 166.666 .max_downscale_factor = { - .argb8888 = 167, + .argb8888 = 250, .nv12 = 167, .fp16 = 167 }, @@ -782,6 +782,7 @@ .psp_disabled_wa = true, .ips2_eval_delay_us = 2000, .ips2_entry_delay_us = 800, + .disable_dmub_reallow_idle = true, .static_screen_wait_frames = 2, }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -3133,6 +3133,14 @@ * Currently the support is only for 0 or 1 */ uint8_t panel_inst; + /** + * 16-bit value dicated by driver that indicates the coasting vtotal high byte part. + */ + uint16_t coasting_vtotal_high; + /** + * Explicit padding to 4 byte boundary. + */ + uint8_t pad[2]; }; /** --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/include/dpcd_defs.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/include/dpcd_defs.h @@ -177,4 +177,9 @@ #define DP_SINK_PR_PIXEL_DEVIATION_PER_LINE 0x379 #define DP_SINK_PR_MAX_NUMBER_OF_DEVIATION_LINE 0x37A +/* Remove once drm_dp_helper.h is updated upstream */ +#ifndef DP_TOTAL_LTTPR_CNT +#define DP_TOTAL_LTTPR_CNT 0xF000A /* 2.1 */ +#endif + #endif /* __DAL_DPCD_DEFS_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c @@ -156,6 +156,10 @@ uint32_t cur_size = 0; uint32_t data_offset = 0; + if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { + return MOD_HDCP_STATUS_DDC_FAILURE; + } + if (is_dp_hdcp(hdcp)) { while (buf_len > 0) { cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); @@ -215,6 +219,10 @@ uint32_t cur_size = 0; uint32_t data_offset = 0; + if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { + return MOD_HDCP_STATUS_DDC_FAILURE; + } + if (is_dp_hdcp(hdcp)) { while (buf_len > 0) { cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -513,6 +513,9 @@ hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory)); + if (!display) + return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; + hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index; if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h @@ -57,10 +57,10 @@ unsigned int length); void mod_stats_update_flip(struct mod_stats *mod_stats, - unsigned long timestamp_in_ns); + unsigned long long timestamp_in_ns); void mod_stats_update_vupdate(struct mod_stats *mod_stats, - unsigned long timestamp_in_ns); + unsigned long long timestamp_in_ns); void mod_stats_update_freesync(struct mod_stats *mod_stats, unsigned int v_total_min, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -147,15 +147,12 @@ } /* VSC packet set to 4 for PSR-SU, or 2 for PSR1 */ - if (stream->link->psr_settings.psr_feature_enabled) { - if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) - vsc_packet_revision = vsc_packet_rev4; - else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) - vsc_packet_revision = vsc_packet_rev2; - } - - if (stream->link->replay_settings.config.replay_supported) + if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) + vsc_packet_revision = vsc_packet_rev4; + else if (stream->link->replay_settings.config.replay_supported) vsc_packet_revision = vsc_packet_rev4; + else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) + vsc_packet_revision = vsc_packet_rev2; /* Update to revision 5 for extended colorimetry support */ if (stream->use_vsc_sdp_for_colorimetry) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -975,7 +975,7 @@ void set_replay_coasting_vtotal(struct dc_link *link, enum replay_coasting_vtotal_type type, - uint16_t vtotal) + uint32_t vtotal) { link->replay_settings.coasting_vtotal_table[type] = vtotal; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.h @@ -56,7 +56,7 @@ void init_replay_config(struct dc_link *link, struct replay_config *pr_config); void set_replay_coasting_vtotal(struct dc_link *link, enum replay_coasting_vtotal_type type, - uint16_t vtotal); + uint32_t vtotal); void set_replay_ips_full_screen_video_src_vtotal(struct dc_link *link, uint16_t vtotal); void calculate_replay_link_off_frame_count(struct dc_link *link, uint16_t vtotal, uint16_t htotal); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/include/atomfirmware.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/include/atomfirmware.h @@ -702,7 +702,7 @@ { struct atom_common_table_header table_header; /*the real number of this included in the structure is calcualted by using the (whole structure size - the header size)/size of atom_gpio_pin_lut */ - struct atom_gpio_pin_assignment gpio_pin[8]; + struct atom_gpio_pin_assignment gpio_pin[]; }; @@ -1625,6 +1625,49 @@ uint32_t reserved4[189]; }; +struct uma_carveout_option { + char optionName[29]; //max length of string is 28chars + '\0'. Current design is for "minimum", "Medium", "High". This makes entire struct size 64bits + uint8_t memoryCarvedGb; //memory carved out with setting + uint8_t memoryRemainingGb; //memory remaining on system + union { + struct _flags { + uint8_t Auto : 1; + uint8_t Custom : 1; + uint8_t Reserved : 6; + } flags; + uint8_t all8; + } uma_carveout_option_flags; +}; + +struct atom_integrated_system_info_v2_3 { + struct atom_common_table_header table_header; + uint32_t vbios_misc; // enum of atom_system_vbiosmisc_def + uint32_t gpucapinfo; // enum of atom_system_gpucapinf_def + uint32_t system_config; + uint32_t cpucapinfo; + uint16_t gpuclk_ss_percentage; // unit of 0.001%, 1000 mean 1% + uint16_t gpuclk_ss_type; + uint16_t dpphy_override; // bit vector, enum of atom_sysinfo_dpphy_override_def + uint8_t memorytype; // enum of atom_dmi_t17_mem_type_def, APU memory type indication. + uint8_t umachannelnumber; // number of memory channels + uint8_t htc_hyst_limit; + uint8_t htc_tmp_limit; + uint8_t reserved1; // dp_ss_control + uint8_t gpu_package_id; + struct edp_info_table edp1_info; + struct edp_info_table edp2_info; + uint32_t reserved2[8]; + struct atom_external_display_connection_info extdispconninfo; + uint8_t UMACarveoutVersion; + uint8_t UMACarveoutIndexMax; + uint8_t UMACarveoutTypeDefault; + uint8_t UMACarveoutIndexDefault; + uint8_t UMACarveoutType; //Auto or Custom + uint8_t UMACarveoutIndex; + struct uma_carveout_option UMASizeControlOption[20]; + uint8_t reserved3[110]; +}; + // system_config enum atom_system_vbiosmisc_def{ INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT = 0x01, @@ -3508,7 +3551,7 @@ uint8_t phase_delay_us; // phase delay in unit of micro second uint8_t reserved; uint32_t gpio_mask_val; // GPIO Mask value - struct atom_voltage_gpio_map_lut voltage_gpio_lut[1]; + struct atom_voltage_gpio_map_lut voltage_gpio_lut[] __counted_by(gpio_entry_num); }; struct atom_svid2_voltage_object_v4 --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/include/pptable.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/include/pptable.h @@ -477,31 +477,30 @@ } ATOM_PPLIB_STATE_V2; typedef struct _StateArray{ - //how many states we have - UCHAR ucNumEntries; - - ATOM_PPLIB_STATE_V2 states[1]; + //how many states we have + UCHAR ucNumEntries; + + ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */; }StateArray; typedef struct _ClockInfoArray{ - //how many clock levels we have - UCHAR ucNumEntries; - - //sizeof(ATOM_PPLIB_CLOCK_INFO) - UCHAR ucEntrySize; - - UCHAR clockInfo[1]; + //how many clock levels we have + UCHAR ucNumEntries; + + //sizeof(ATOM_PPLIB_CLOCK_INFO) + UCHAR ucEntrySize; + + UCHAR clockInfo[]; }ClockInfoArray; typedef struct _NonClockInfoArray{ + //how many non-clock levels we have. normally should be same as number of states + UCHAR ucNumEntries; + //sizeof(ATOM_PPLIB_NONCLOCK_INFO) + UCHAR ucEntrySize; - //how many non-clock levels we have. normally should be same as number of states - UCHAR ucNumEntries; - //sizeof(ATOM_PPLIB_NONCLOCK_INFO) - UCHAR ucEntrySize; - - ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1]; + ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries); }NonClockInfoArray; typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record @@ -513,8 +512,10 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table { - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries. + // Number of entries. + UCHAR ucNumEntries; + // Dynamically allocate entries. + ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[] __counted_by(ucNumEntries); }ATOM_PPLIB_Clock_Voltage_Dependency_Table; typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record @@ -529,8 +530,10 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table { - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries. + // Number of entries. + UCHAR ucNumEntries; + // Dynamically allocate entries. + ATOM_PPLIB_Clock_Voltage_Limit_Record entries[] __counted_by(ucNumEntries); }ATOM_PPLIB_Clock_Voltage_Limit_Table; union _ATOM_PPLIB_CAC_Leakage_Record @@ -553,8 +556,10 @@ typedef struct _ATOM_PPLIB_CAC_Leakage_Table { - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_CAC_Leakage_Record entries[1]; // Dynamically allocate entries. + // Number of entries. + UCHAR ucNumEntries; + // Dynamically allocate entries. + ATOM_PPLIB_CAC_Leakage_Record entries[] __counted_by(ucNumEntries); }ATOM_PPLIB_CAC_Leakage_Table; typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record @@ -568,8 +573,10 @@ typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table { - UCHAR ucNumEntries; // Number of entries. - ATOM_PPLIB_PhaseSheddingLimits_Record entries[1]; // Dynamically allocate entries. + // Number of entries. + UCHAR ucNumEntries; + // Dynamically allocate entries. + ATOM_PPLIB_PhaseSheddingLimits_Record entries[] __counted_by(ucNumEntries); }ATOM_PPLIB_PhaseSheddingLimits_Table; typedef struct _VCEClockInfo{ @@ -580,8 +587,8 @@ }VCEClockInfo; typedef struct _VCEClockInfoArray{ - UCHAR ucNumEntries; - VCEClockInfo entries[1]; + UCHAR ucNumEntries; + VCEClockInfo entries[] __counted_by(ucNumEntries); }VCEClockInfoArray; typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record @@ -592,8 +599,8 @@ typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table { - UCHAR numEntries; - ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1]; + UCHAR numEntries; + ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries); }ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table; typedef struct _ATOM_PPLIB_VCE_State_Record @@ -604,8 +611,8 @@ typedef struct _ATOM_PPLIB_VCE_State_Table { - UCHAR numEntries; - ATOM_PPLIB_VCE_State_Record entries[1]; + UCHAR numEntries; + ATOM_PPLIB_VCE_State_Record entries[] __counted_by(numEntries); }ATOM_PPLIB_VCE_State_Table; @@ -626,8 +633,8 @@ }UVDClockInfo; typedef struct _UVDClockInfoArray{ - UCHAR ucNumEntries; - UVDClockInfo entries[1]; + UCHAR ucNumEntries; + UVDClockInfo entries[] __counted_by(ucNumEntries); }UVDClockInfoArray; typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record @@ -638,8 +645,8 @@ typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table { - UCHAR numEntries; - ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1]; + UCHAR numEntries; + ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries); }ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table; typedef struct _ATOM_PPLIB_UVD_Table @@ -657,8 +664,8 @@ }ATOM_PPLIB_SAMClk_Voltage_Limit_Record; typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{ - UCHAR numEntries; - ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[1]; + UCHAR numEntries; + ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[] __counted_by(numEntries); }ATOM_PPLIB_SAMClk_Voltage_Limit_Table; typedef struct _ATOM_PPLIB_SAMU_Table @@ -675,8 +682,8 @@ }ATOM_PPLIB_ACPClk_Voltage_Limit_Record; typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Table{ - UCHAR numEntries; - ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[1]; + UCHAR numEntries; + ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[] __counted_by(numEntries); }ATOM_PPLIB_ACPClk_Voltage_Limit_Table; typedef struct _ATOM_PPLIB_ACP_Table @@ -743,9 +750,9 @@ } ATOM_PPLIB_VQ_Budgeting_Record; typedef struct ATOM_PPLIB_VQ_Budgeting_Table { - UCHAR revid; - UCHAR numEntries; - ATOM_PPLIB_VQ_Budgeting_Record entries[1]; + UCHAR revid; + UCHAR numEntries; + ATOM_PPLIB_VQ_Budgeting_Record entries[] __counted_by(numEntries); } ATOM_PPLIB_VQ_Budgeting_Table; #pragma pack() --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -4217,6 +4217,13 @@ } } + /* + * If gpu_od is the only member in the list, that means gpu_od is an + * empty directory, so remove it. + */ + if (list_is_singular(&adev->pm.od_kobj_list)) + goto err_out; + return 0; err_out: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c @@ -164,6 +164,8 @@ for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { if (table[i].ulSupportedSCLK != 0) { + if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) + continue; vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = table[i].usVoltageID; vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -734,7 +734,7 @@ smu->adev = adev; smu->pm_enabled = !!amdgpu_dpm; smu->is_apu = false; - smu->smu_baco.state = SMU_BACO_STATE_EXIT; + smu->smu_baco.state = SMU_BACO_STATE_NONE; smu->smu_baco.platform_support = false; smu->user_dpm_profile.fan_mode = -1; @@ -1954,10 +1954,25 @@ return 0; } +static int smu_reset_mp1_state(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + int ret = 0; + + if ((!adev->in_runpm) && (!adev->in_suspend) && + (!amdgpu_in_reset(adev)) && amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(13, 0, 10) && + !amdgpu_device_has_display_hardware(adev)) + ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD); + + return ret; +} + static int smu_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = adev->powerplay.pp_handle; + int ret; if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; @@ -1975,7 +1990,15 @@ adev->pm.dpm_enabled = false; - return smu_smc_hw_cleanup(smu); + ret = smu_smc_hw_cleanup(smu); + if (ret) + return ret; + + ret = smu_reset_mp1_state(smu); + if (ret) + return ret; + + return 0; } static void smu_late_fini(void *handle) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -424,6 +424,7 @@ enum smu_baco_state { SMU_BACO_STATE_ENTER = 0, SMU_BACO_STATE_EXIT, + SMU_BACO_STATE_NONE, }; struct smu_baco_context { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -1285,8 +1285,9 @@ { struct smu_11_0_powerplay_table *powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; + struct smu_11_0_overdrive_table *od_settings = smu->od_settings; PPTable_t *pptable = smu->smu_table.driver_pptable; - uint32_t power_limit, od_percent_upper, od_percent_lower; + uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { /* the last hope to figure out the ppt limit */ @@ -1303,12 +1304,16 @@ if (default_power_limit) *default_power_limit = power_limit; - if (smu->od_enabled) - od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); - else - od_percent_upper = 0; - - od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + if (powerplay_table) { + if (smu->od_enabled && + od_settings->cap[SMU_11_0_ODCAP_POWER_LIMIT]) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + } else if (od_settings->cap[SMU_11_0_ODCAP_POWER_LIMIT]) { + od_percent_upper = 0; + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + } + } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", od_percent_upper, od_percent_lower, power_limit); @@ -2272,8 +2277,8 @@ /* TODO: confirm this on real target */ esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL); - if ((esm_ctrl >> 15) & 0x1FFFF) - return (uint16_t)(((esm_ctrl >> 8) & 0x3F) + 128); + if ((esm_ctrl >> 15) & 0x1) + return (uint16_t)(((esm_ctrl >> 8) & 0x7F) + 128); return smu_v11_0_get_current_pcie_link_speed(smu); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -2339,7 +2339,7 @@ (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; struct smu_11_0_overdrive_table *od_settings = smu->od_settings; PPTable_t *pptable = smu->smu_table.driver_pptable; - uint32_t power_limit, od_percent_upper, od_percent_lower; + uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { /* the last hope to figure out the ppt limit */ @@ -2356,13 +2356,16 @@ if (default_power_limit) *default_power_limit = power_limit; - if (smu->od_enabled && - navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) - od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); - else - od_percent_upper = 0; - - od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + if (powerplay_table) { + if (smu->od_enabled && + navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + } else if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) { + od_percent_upper = 0; + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + } + } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", od_percent_upper, od_percent_lower, power_limit); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -617,6 +617,12 @@ return throttler_status; } +static bool sienna_cichlid_is_od_feature_supported(struct smu_11_0_7_overdrive_table *od_table, + enum SMU_11_0_7_ODFEATURE_CAP cap) +{ + return od_table->cap[cap]; +} + static int sienna_cichlid_get_power_limit(struct smu_context *smu, uint32_t *current_power_limit, uint32_t *default_power_limit, @@ -625,7 +631,8 @@ { struct smu_11_0_7_powerplay_table *powerplay_table = (struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table; - uint32_t power_limit, od_percent_upper, od_percent_lower; + struct smu_11_0_7_overdrive_table *od_settings = smu->od_settings; + uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; uint16_t *table_member; GET_PPTABLE_MEMBER(SocketPowerLimitAc, &table_member); @@ -640,12 +647,16 @@ if (default_power_limit) *default_power_limit = power_limit; - if (smu->od_enabled) - od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); - else - od_percent_upper = 0; - - od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + if (powerplay_table) { + if (smu->od_enabled && + sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_POWER_LIMIT)) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + } else if ((sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_POWER_LIMIT))) { + od_percent_upper = 0; + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + } + } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", od_percent_upper, od_percent_lower, power_limit); @@ -1250,12 +1261,6 @@ return dpm_desc->SnapToDiscrete == 0; } -static bool sienna_cichlid_is_od_feature_supported(struct smu_11_0_7_overdrive_table *od_table, - enum SMU_11_0_7_ODFEATURE_CAP cap) -{ - return od_table->cap[cap]; -} - static void sienna_cichlid_get_od_setting_range(struct smu_11_0_7_overdrive_table *od_table, enum SMU_11_0_7_ODSETTING_ID setting, uint32_t *min, uint32_t *max) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -1682,8 +1682,8 @@ /* TODO: confirm this on real target */ esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL); - if ((esm_ctrl >> 15) & 0x1FFFF) - return (((esm_ctrl >> 8) & 0x3F) + 128); + if ((esm_ctrl >> 15) & 0x1) + return (((esm_ctrl >> 8) & 0x7F) + 128); return smu_v13_0_get_current_pcie_link_speed(smu); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -2356,7 +2356,7 @@ (struct smu_13_0_0_powerplay_table *)table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; SkuTable_t *skutable = &pptable->SkuTable; - uint32_t power_limit, od_percent_upper, od_percent_lower; + uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; if (smu_v13_0_get_current_power_limit(smu, &power_limit)) @@ -2369,12 +2369,16 @@ if (default_power_limit) *default_power_limit = power_limit; - if (smu->od_enabled) - od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); - else - od_percent_upper = 0; - - od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + if (powerplay_table) { + if (smu->od_enabled && + smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + } else if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { + od_percent_upper = 0; + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + } + } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", od_percent_upper, od_percent_lower, power_limit); @@ -2747,7 +2751,13 @@ switch (mp1_state) { case PP_MP1_STATE_UNLOAD: - ret = smu_cmn_set_mp1_state(smu, mp1_state); + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_PrepareMp1ForUnload, + 0x55, NULL); + + if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) + ret = smu_v13_0_disable_pmfw_state(smu); + break; default: /* Ignore others */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -226,8 +226,20 @@ struct amdgpu_device *adev = smu->adev; int ret = 0; - if (!en && !adev->in_s0ix) + if (!en && !adev->in_s0ix) { + if (adev->in_s4) { + /* Adds a GFX reset as workaround just before sending the + * MP1_UNLOAD message to prevent GC/RLC/PMFW from entering + * an invalid state. + */ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, + SMU_RESET_MODE_2, NULL); + if (ret) + return ret; + } + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); + } return ret; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -2060,8 +2060,8 @@ /* TODO: confirm this on real target */ esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL); - if ((esm_ctrl >> 15) & 0x1FFFF) - return (((esm_ctrl >> 8) & 0x3F) + 128); + if ((esm_ctrl >> 15) & 0x1) + return (((esm_ctrl >> 8) & 0x7F) + 128); speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) @@ -2205,6 +2205,17 @@ return sizeof(*gpu_metrics); } +static void smu_v13_0_6_restore_pci_config(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + int i; + + for (i = 0; i < 16; i++) + pci_write_config_dword(adev->pdev, i * 4, + adev->pdev->saved_config_space[i]); + pci_restore_msi_state(adev->pdev); +} + static int smu_v13_0_6_mode2_reset(struct smu_context *smu) { int ret = 0, index; @@ -2226,6 +2237,20 @@ /* Restore the config space saved during init */ amdgpu_device_load_pci_state(adev->pdev); + /* Certain platforms have switches which assign virtual BAR values to + * devices. OS uses the virtual BAR values and device behind the switch + * is assgined another BAR value. When device's config space registers + * are queried, switch returns the virtual BAR values. When mode-2 reset + * is performed, switch is unaware of it, and will continue to return + * the same virtual values to the OS.This affects + * pci_restore_config_space() API as it doesn't write the value saved if + * the current value read from config space is the same as what is + * saved. As a workaround, make sure the config space is restored + * always. + */ + if (!(adev->flags & AMD_IS_APU)) + smu_v13_0_6_restore_pci_config(smu); + dev_dbg(smu->adev->dev, "wait for reset ack\n"); do { ret = smu_cmn_wait_for_response(smu); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -2320,7 +2320,7 @@ (struct smu_13_0_7_powerplay_table *)table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; SkuTable_t *skutable = &pptable->SkuTable; - uint32_t power_limit, od_percent_upper, od_percent_lower; + uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; if (smu_v13_0_get_current_power_limit(smu, &power_limit)) @@ -2333,12 +2333,16 @@ if (default_power_limit) *default_power_limit = power_limit; - if (smu->od_enabled) - od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); - else - od_percent_upper = 0; - - od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + if (powerplay_table) { + if (smu->od_enabled && + (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT))) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + } else if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) { + od_percent_upper = 0; + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + } + } dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", od_percent_upper, od_percent_lower, power_limit); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -259,7 +259,7 @@ u32 avail_scalers; pipe_st = komeda_pipeline_get_state(c->pipeline, state); - if (!pipe_st) + if (IS_ERR_OR_NULL(pipe_st)) return NULL; avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/arm/malidp_mw.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/arm/malidp_mw.c @@ -72,7 +72,10 @@ __drm_atomic_helper_connector_destroy_state(connector->state); kfree(connector->state); - __drm_atomic_helper_connector_reset(connector, &mw_state->base); + connector->state = NULL; + + if (mw_state) + __drm_atomic_helper_connector_reset(connector, &mw_state->base); } static enum drm_connector_status --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ast/ast_dp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/ast/ast_dp.c @@ -180,6 +180,7 @@ { struct ast_device *ast = to_ast_device(dev); u8 video_on_off = on; + u32 i = 0; // Video On/Off ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); @@ -192,6 +193,8 @@ ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) { // wait 1 ms mdelay(1); + if (++i > 200) + break; } } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1277,17 +1277,6 @@ INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); - if (i2c->irq) { - init_waitqueue_head(&adv7511->wq); - - ret = devm_request_threaded_irq(dev, i2c->irq, NULL, - adv7511_irq_handler, - IRQF_ONESHOT, dev_name(dev), - adv7511); - if (ret) - goto err_unregister_cec; - } - adv7511_power_off(adv7511); i2c_set_clientdata(i2c, adv7511); @@ -1311,6 +1300,17 @@ adv7511_audio_init(dev, adv7511); + if (i2c->irq) { + init_waitqueue_head(&adv7511->wq); + + ret = devm_request_threaded_irq(dev, i2c->irq, NULL, + adv7511_irq_handler, + IRQF_ONESHOT, dev_name(dev), + adv7511); + if (ret) + goto err_unregister_audio; + } + if (adv7511->info->has_dsi) { ret = adv7533_attach_dsi(adv7511); if (ret) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/analogix/anx7625.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2076,10 +2076,8 @@ }; host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node); - if (!host) { - DRM_DEV_ERROR(dev, "fail to find dsi host.\n"); - return -EPROBE_DEFER; - } + if (!host) + return dev_err_probe(dev, -EPROBE_DEFER, "fail to find dsi host.\n"); dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { @@ -2481,15 +2479,22 @@ mutex_unlock(&ctx->aux_lock); } +static void +anx7625_audio_update_connector_status(struct anx7625_data *ctx, + enum drm_connector_status status); + static enum drm_connector_status anx7625_bridge_detect(struct drm_bridge *bridge) { struct anx7625_data *ctx = bridge_to_anx7625(bridge); struct device *dev = ctx->dev; + enum drm_connector_status status; DRM_DEV_DEBUG_DRIVER(dev, "drm bridge detect\n"); - return anx7625_sink_detect(ctx); + status = anx7625_sink_detect(ctx); + anx7625_audio_update_connector_status(ctx, status); + return status; } static struct edid *anx7625_bridge_get_edid(struct drm_bridge *bridge, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -2057,6 +2057,9 @@ mhdp_state = to_cdns_mhdp_bridge_state(new_state); mhdp_state->current_mode = drm_mode_duplicate(bridge->dev, mode); + if (!mhdp_state->current_mode) + return; + drm_mode_set_name(mhdp_state->current_mode); dev_dbg(mhdp->dev, "%s: Enabling mode %s\n", __func__, mode->name); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/chipone-icn6211.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -563,10 +563,8 @@ host = of_find_mipi_dsi_host_by_node(host_node); of_node_put(host_node); - if (!host) { - dev_err(dev, "failed to find dsi host\n"); - return -EPROBE_DEFER; - } + if (!host) + return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n"); dsi = mipi_dsi_device_register_full(host, &info); if (IS_ERR(dsi)) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/lontium-lt8912b.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/lontium-lt8912b.c @@ -440,26 +440,24 @@ static int lt8912_connector_get_modes(struct drm_connector *connector) { - struct edid *edid; - int ret = -1; - int num = 0; + const struct drm_edid *drm_edid; struct lt8912 *lt = connector_to_lt8912(connector); u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; + int ret, num; + + drm_edid = drm_bridge_edid_read(lt->hdmi_port, connector); + drm_edid_connector_update(connector, drm_edid); + if (!drm_edid) + return 0; - edid = drm_bridge_get_edid(lt->hdmi_port, connector); - if (edid) { - drm_connector_update_edid_property(connector, edid); - num = drm_add_edid_modes(connector, edid); - } else { - return ret; - } + num = drm_edid_connector_add_modes(connector); ret = drm_display_info_set_bus_formats(&connector->display_info, &bus_format, 1); - if (ret) - num = ret; + if (ret < 0) + num = 0; - kfree(edid); + drm_edid_free(drm_edid); return num; } @@ -496,10 +494,8 @@ }; host = of_find_mipi_dsi_host_by_node(lt->host_node); - if (!host) { - dev_err(dev, "failed to find dsi host\n"); - return -EPROBE_DEFER; - } + if (!host) + return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n"); dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/lontium-lt9611.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -760,10 +760,8 @@ int ret; host = of_find_mipi_dsi_host_by_node(dsi_node); - if (!host) { - dev_err(lt9611->dev, "failed to find dsi host\n"); - return ERR_PTR(-EPROBE_DEFER); - } + if (!host) + return ERR_PTR(dev_err_probe(lt9611->dev, -EPROBE_DEFER, "failed to find dsi host\n")); dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -265,10 +265,8 @@ int ret; host = of_find_mipi_dsi_host_by_node(dsi_node); - if (!host) { - dev_err(dev, "failed to find dsi host\n"); - return ERR_PTR(-EPROBE_DEFER); - } + if (!host) + return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n")); dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/panel.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/panel.c @@ -358,9 +358,12 @@ static void devm_drm_panel_bridge_release(struct device *dev, void *res) { - struct drm_bridge **bridge = res; + struct drm_bridge *bridge = *(struct drm_bridge **)res; - drm_panel_bridge_remove(*bridge); + if (!bridge) + return; + + drm_bridge_remove(bridge); } /** --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/tc358775.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/tc358775.c @@ -454,10 +454,6 @@ dev_dbg(tc->dev, "bus_formats %04x bpc %d\n", connector->display_info.bus_formats[0], tc->bpc); - /* - * Default hardware register settings of tc358775 configured - * with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format - */ if (connector->display_info.bus_formats[0] == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) { /* VESA-24 */ @@ -468,14 +464,15 @@ d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2)); d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0)); d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6)); - } else { /* MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */ - d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3)); - d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, LVI_G0)); - d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, LVI_L0)); - d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0)); - d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, LVI_B2)); - d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0)); - d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_L0)); + } else { + /* JEIDA-18 and JEIDA-24 */ + d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, LVI_R5)); + d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, LVI_G2)); + d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, LVI_G1)); + d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, LVI_B2)); + d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, LVI_B4)); + d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, LVI_L0)); + d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R0)); } d2l_write(tc->i2c, VFUEN, VFUEN_EN); @@ -610,10 +607,8 @@ }; host = of_find_mipi_dsi_host_by_node(tc->host_node); - if (!host) { - dev_err(dev, "failed to find dsi host\n"); - return -EPROBE_DEFER; - } + if (!host) + return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n"); dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/ti-dlpc3433.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/ti-dlpc3433.c @@ -319,12 +319,11 @@ .channel = 0, .node = NULL, }; + int ret; host = of_find_mipi_dsi_host_by_node(dlpc->host_node); - if (!host) { - DRM_DEV_ERROR(dev, "failed to find dsi host\n"); - return -EPROBE_DEFER; - } + if (!host) + return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n"); dlpc->dsi = mipi_dsi_device_register_full(host, &info); if (IS_ERR(dlpc->dsi)) { @@ -336,7 +335,11 @@ dlpc->dsi->format = MIPI_DSI_FMT_RGB565; dlpc->dsi->lanes = dlpc->dsi_lanes; - return devm_mipi_dsi_attach(dev, dlpc->dsi); + ret = devm_mipi_dsi_attach(dev, dlpc->dsi); + if (ret) + DRM_DEV_ERROR(dev, "failed to attach dsi host\n"); + + return ret; } static int dlpc3433_probe(struct i2c_client *client) @@ -367,10 +370,8 @@ drm_bridge_add(&dlpc->bridge); ret = dlpc_host_attach(dlpc); - if (ret) { - DRM_DEV_ERROR(dev, "failed to attach dsi host\n"); + if (ret) goto err_remove_bridge; - } return 0; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -478,7 +478,6 @@ dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret); /* On failure, disable PLL again and exit. */ regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00); - regulator_disable(ctx->vcc); return; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -1591,7 +1591,6 @@ pdata->pchip.ops = &ti_sn_pwm_ops; pdata->pchip.npwm = 1; pdata->pchip.of_xlate = of_pwm_single_xlate; - pdata->pchip.of_pwm_n_cells = 1; devm_pm_runtime_enable(&adev->dev); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ci/gitlab-ci.yml +++ linux-xilinx-6.8.0/drivers/gpu/drm/ci/gitlab-ci.yml @@ -1,6 +1,6 @@ variables: DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa - DRM_CI_COMMIT_SHA: &drm-ci-commit-sha edfbf74df1d4d6ce54ffe24566108be0e1a98c3d + DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 9d162de9a05155e1c4041857a5848842749164cf UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm TARGET_BRANCH: drm-next @@ -25,7 +25,9 @@ # per-job artifact storage on MinIO JOB_ARTIFACTS_BASE: ${PIPELINE_ARTIFACTS_BASE}/${CI_JOB_ID} # default kernel for rootfs before injecting the current kernel tree - KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/gfx-ci/linux/v6.4.12-for-mesa-ci-f6b4ad45f48d + KERNEL_REPO: "gfx-ci/linux" + KERNEL_TAG: "v6.6.4-for-mesa-ci-e4f4c500f7fb" + KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/${KERNEL_REPO}/${KERNEL_TAG} LAVA_TAGS: subset-1-gfx LAVA_JOB_PRIORITY: 30 @@ -133,6 +135,11 @@ - if: &is-pre-merge-for-marge '$GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"' when: on_success +.never-post-merge-rules: + rules: + - if: *is-post-merge + when: never + # Rule to filter for only scheduled pipelines. .scheduled_pipeline-rules: rules: @@ -150,6 +157,7 @@ .build-rules: rules: - !reference [.no_scheduled_pipelines-rules, rules] + - !reference [.never-post-merge-rules, rules] # Run automatically once all dependency jobs have passed - when: on_success @@ -157,6 +165,7 @@ .container+build-rules: rules: - !reference [.no_scheduled_pipelines-rules, rules] + - !reference [.never-post-merge-rules, rules] - when: manual .ci-deqp-artifacts: @@ -175,6 +184,7 @@ .container-rules: rules: - !reference [.no_scheduled_pipelines-rules, rules] + - !reference [.never-post-merge-rules, rules] # Run pipeline by default in the main project if any CI pipeline # configuration files were changed, to ensure docker images are up to date - if: *is-post-merge --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ci/test.yml +++ linux-xilinx-6.8.0/drivers/gpu/drm/ci/test.yml @@ -104,7 +104,10 @@ DRIVER_NAME: msm BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8016-sbc-usb-host.dtb GPU_VERSION: apq8016 - BM_CMDLINE: "ip=dhcp console=ttyMSM0,115200n8 $BM_KERNEL_EXTRA_ARGS root=/dev/nfs rw nfsrootdebug nfsroot=,tcp,nfsvers=4.2 init=/init $BM_KERNELARGS" + # disabling unused clocks congests with the MDSS runtime PM trying to + # disable those clocks and causes boot to fail. + # Reproducer: DRM_MSM=y, DRM_I2C_ADV7511=m + BM_KERNEL_EXTRA_ARGS: clk_ignore_unused RUNNER_TAG: google-freedreno-db410c script: - ./install/bare-metal/fastboot.sh @@ -234,11 +237,11 @@ i915:tgl: extends: - .i915 - parallel: 8 + parallel: 5 variables: - DEVICE_TYPE: asus-cx9400-volteer + DEVICE_TYPE: acer-cp514-2h-1130g7-volteer GPU_VERSION: tgl - RUNNER_TAG: mesa-ci-x86-64-lava-asus-cx9400-volteer + RUNNER_TAG: mesa-ci-x86-64-lava-acer-cp514-2h-1130g7-volteer .amdgpu: extends: @@ -324,6 +327,7 @@ GPU_VERSION: none extends: - .test-gl + - .test-rules tags: - kvm script: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/display/drm_dp_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/display/drm_dp_helper.c @@ -533,6 +533,15 @@ mutex_lock(&aux->hw_mutex); /* + * If the device attached to the aux bus is powered down then there's + * no reason to attempt a transfer. Error out immediately. + */ + if (aux->powered_down) { + ret = -EBUSY; + goto unlock; + } + + /* * The specification doesn't give any recommendation on how often to * retry native transactions. We used to retry 7 times like for * aux i2c transactions but real world devices this wasn't @@ -600,6 +609,29 @@ EXPORT_SYMBOL(drm_dp_dpcd_probe); /** + * drm_dp_dpcd_set_powered() - Set whether the DP device is powered + * @aux: DisplayPort AUX channel; for convenience it's OK to pass NULL here + * and the function will be a no-op. + * @powered: true if powered; false if not + * + * If the endpoint device on the DP AUX bus is known to be powered down + * then this function can be called to make future transfers fail immediately + * instead of needing to time out. + * + * If this function is never called then a device defaults to being powered. + */ +void drm_dp_dpcd_set_powered(struct drm_dp_aux *aux, bool powered) +{ + if (!aux) + return; + + mutex_lock(&aux->hw_mutex); + aux->powered_down = !powered; + mutex_unlock(&aux->hw_mutex); +} +EXPORT_SYMBOL(drm_dp_dpcd_set_powered); + +/** * drm_dp_dpcd_read() - read a series of bytes from the DPCD * @aux: DisplayPort AUX channel (SST or MST) * @offset: address of the (first) register to read @@ -1858,6 +1890,9 @@ struct drm_dp_aux_msg msg; int err = 0; + if (aux->powered_down) + return -EBUSY; + dp_aux_i2c_transfer_size = clamp(dp_aux_i2c_transfer_size, 1, DP_AUX_MAX_PAYLOAD_BYTES); memset(&msg, 0, sizeof(msg)); @@ -2097,8 +2132,6 @@ { int ret; - WARN_ON_ONCE(!aux->drm_dev); - if (!aux->ddc.algo) drm_dp_aux_init(aux); @@ -3982,6 +4015,13 @@ u32 overhead = 1000000; int symbol_cycles; + if (lane_count == 0 || hactive == 0 || bpp_x16 == 0) { + DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, hactive %d, bpp_x16 %d.%04d\n", + lane_count, hactive, + bpp_x16 >> 4, (bpp_x16 & 0xf) * 625); + return 0; + } + /* * DP Standard v2.1 2.6.4.1 * SSC downspread and ref clock variation margin: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3416,7 +3416,6 @@ /** * drm_dp_add_payload_part2() - Execute payload update part 2 * @mgr: Manager to use. - * @state: The global atomic state * @payload: The payload to update * * If @payload was successfully assigned a starting time slot by drm_dp_add_payload_part1(), this @@ -3425,14 +3424,13 @@ * Returns: 0 on success, negative error code on failure. */ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr, - struct drm_atomic_state *state, struct drm_dp_mst_atomic_payload *payload) { int ret = 0; /* Skip failed payloads */ if (payload->payload_allocation_status != DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) { - drm_dbg_kms(state->dev, "Part 1 of payload creation for %s failed, skipping part 2\n", + drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n", payload->port->connector->name); return -EIO; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/display/drm_hdmi_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/display/drm_hdmi_helper.c @@ -78,6 +78,81 @@ } EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata); + +/** + * drm_hdmi_infoframe_set_gen_hdr_metadata() - fill an HDMI DRM infoframe with + * HDR metadata from userspace + * @frame: HDMI DRM infoframe + * @conn_state: Connector state containing HDR metadata + * + * Return: 0 on success or a negative error code on failure. + */ +int +drm_hdmi_infoframe_set_gen_hdr_metadata(struct hdmi_drm_infoframe *frame, + const struct drm_connector_state *conn_state) +{ + struct drm_connector *connector; + struct gen_hdr_output_metadata *gen_hdr_metadata; + struct hdr_metadata_infoframe *hdr_infoframe; + int err; + + if (!frame || !conn_state) + return -EINVAL; + + connector = conn_state->connector; + + if (!conn_state->gen_hdr_output_metadata) + return -EINVAL; + + gen_hdr_metadata = conn_state->gen_hdr_output_metadata->data; + + if (!gen_hdr_metadata || !connector) + return -EINVAL; + + if (gen_hdr_metadata->metadata_type == DRM_HDR_TYPE_HDR10) { + hdr_infoframe = (struct hdr_metadata_infoframe *) + gen_hdr_metadata->payload; + + /* Sink EOTF is Bit map while infoframe is absolute values */ + if (!is_eotf_supported(hdr_infoframe->eotf, + connector->hdr_sink_metadata.hdmi_type1.eotf)) { + DRM_DEBUG_KMS("EOTF Not Supported\n"); + return -EINVAL; + } + + err = hdmi_drm_infoframe_init(frame); + if (err < 0) + return err; + + frame->eotf = hdr_infoframe->eotf; + frame->metadata_type = hdr_infoframe->metadata_type; + + BUILD_BUG_ON(sizeof(frame->display_primaries) != + sizeof(hdr_infoframe->display_primaries)); + BUILD_BUG_ON(sizeof(frame->white_point) != + sizeof(hdr_infoframe->white_point)); + + memcpy(&frame->display_primaries, + &hdr_infoframe->display_primaries, + sizeof(frame->display_primaries)); + + memcpy(&frame->white_point, + &hdr_infoframe->white_point, + sizeof(frame->white_point)); + + frame->max_display_mastering_luminance = + hdr_infoframe->max_display_mastering_luminance; + frame->min_display_mastering_luminance = + hdr_infoframe->min_display_mastering_luminance; + frame->max_fall = hdr_infoframe->max_fall; + frame->max_cll = hdr_infoframe->max_cll; + } + + return 0; +} +EXPORT_SYMBOL(drm_hdmi_infoframe_set_gen_hdr_metadata); + + /* HDMI Colorspace Spec Definitions */ #define FULL_COLORIMETRY_MASK 0x1FF #define NORMAL_COLORIMETRY_MASK 0x3 --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_atomic_state_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_atomic_state_helper.c @@ -640,6 +640,9 @@ if (state->hdr_output_metadata) drm_property_blob_get(state->hdr_output_metadata); + if (state->gen_hdr_output_metadata) + drm_property_blob_get(state->gen_hdr_output_metadata); + /* Don't copy over a writeback job, they are used only once */ state->writeback_job = NULL; } @@ -689,6 +692,7 @@ drm_writeback_cleanup_job(state->writeback_job); drm_property_blob_put(state->hdr_output_metadata); + drm_property_blob_put(state->gen_hdr_output_metadata); } EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_atomic_uapi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_atomic_uapi.c @@ -742,6 +742,13 @@ sizeof(struct hdr_output_metadata), -1, &replaced); return ret; + } else if (property == config->gen_hdr_output_metadata_property) { + ret = drm_property_replace_blob_from_id(dev, + &state->gen_hdr_output_metadata, + val, + sizeof(struct gen_hdr_output_metadata), -1, + &replaced); + return ret; } else if (property == config->aspect_ratio_property) { state->picture_aspect_ratio = val; } else if (property == config->content_type_property) { @@ -846,6 +853,9 @@ } else if (property == config->hdr_output_metadata_property) { *val = state->hdr_output_metadata ? state->hdr_output_metadata->base.id : 0; + } else if (property == config->gen_hdr_output_metadata_property) { + *val = state->gen_hdr_output_metadata ? + state->gen_hdr_output_metadata->base.id : 0; } else if (property == config->content_protection_property) { *val = state->content_protection; } else if (property == config->hdcp_content_type_property) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_bridge.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_bridge.c @@ -27,8 +27,9 @@ #include #include -#include #include +#include +#include #include #include #include @@ -686,11 +687,17 @@ */ list_for_each_entry_from(next, &encoder->bridge_chain, chain_node) { - if (next->pre_enable_prev_first) { + if (!next->pre_enable_prev_first) { next = list_prev_entry(next, chain_node); limit = next; break; } + + if (list_is_last(&next->chain_node, + &encoder->bridge_chain)) { + limit = next; + break; + } } /* Call these bridges in reverse order */ @@ -773,7 +780,7 @@ /* Found first bridge that does NOT * request prev to be enabled first */ - limit = list_prev_entry(next, chain_node); + limit = next; break; } } @@ -1207,6 +1214,47 @@ EXPORT_SYMBOL_GPL(drm_bridge_get_modes); /** + * drm_bridge_edid_read - read the EDID data of the connected display + * @bridge: bridge control structure + * @connector: the connector to read EDID for + * + * If the bridge supports output EDID retrieval, as reported by the + * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.edid_read to get + * the EDID and return it. Otherwise return NULL. + * + * If &drm_bridge_funcs.edid_read is not set, fall back to using + * drm_bridge_get_edid() and wrapping it in struct drm_edid. + * + * RETURNS: + * The retrieved EDID on success, or NULL otherwise. + */ +const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge, + struct drm_connector *connector) +{ + if (!(bridge->ops & DRM_BRIDGE_OP_EDID)) + return NULL; + + /* Transitional: Fall back to ->get_edid. */ + if (!bridge->funcs->edid_read) { + const struct drm_edid *drm_edid; + struct edid *edid; + + edid = drm_bridge_get_edid(bridge, connector); + if (!edid) + return NULL; + + drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH); + + kfree(edid); + + return drm_edid; + } + + return bridge->funcs->edid_read(bridge, connector); +} +EXPORT_SYMBOL_GPL(drm_bridge_edid_read); + +/** * drm_bridge_get_edid - get the EDID data of the connected display * @bridge: bridge control structure * @connector: the connector to read EDID for @@ -1215,6 +1263,8 @@ * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to * get the EDID and return it. Otherwise return NULL. * + * Deprecated. Prefer using drm_bridge_edid_read(). + * * RETURNS: * The retrieved EDID on success, or NULL otherwise. */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_client_modeset.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_client_modeset.c @@ -777,6 +777,7 @@ unsigned int total_modes_count = 0; struct drm_client_offset *offsets; unsigned int connector_count = 0; + /* points to modes protected by mode_config.mutex */ struct drm_display_mode **modes; struct drm_crtc **crtcs; int i, ret = 0; @@ -845,7 +846,6 @@ drm_client_pick_crtcs(client, connectors, connector_count, crtcs, modes, 0, width, height); } - mutex_unlock(&dev->mode_config.mutex); drm_client_modeset_release(client); @@ -875,6 +875,7 @@ modeset->y = offset->y; } } + mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&client->modeset_mutex); out: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_connector.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_connector.c @@ -1389,6 +1389,14 @@ * hdmi_drm_infoframe_pack() to pack the infoframe as per spec, in case of * HDMI encoder. * + * GEN_HDR_OUTPUT_METADATA: + * This connector property is functionally the same as HDR_OUTPUT_METADATA. + * However, the existing structures for HDR_OUTPUT_METADATA are not flexible + * enough for dynamic HDR or other connectivity devices like SDI. So, this + * property was created to utilize more generic structures that would be + * scalable in the future. This is currently experimental and may possibly + * be merged with the original HDR_OUTPUT_METADATA property in the future. + * * max bpc: * This range property is used by userspace to limit the bit depth. When * used the driver would limit the bpc in accordance with the valid range @@ -1553,6 +1561,12 @@ return -ENOMEM; dev->mode_config.hdr_output_metadata_property = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, + "GEN_HDR_OUTPUT_METADATA", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.gen_hdr_output_metadata_property = prop; + return 0; } @@ -2940,7 +2954,7 @@ dev->mode_config.max_width, dev->mode_config.max_height); else - drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe", + drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe\n", connector->base.id, connector->name); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_edid.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_edid.c @@ -2976,6 +2976,57 @@ (mode->vsync_start - mode->vdisplay == 3); } +/** + * drm_mode_find_cea - Create a copy of a mode if present in CEA + * @dev: Device to duplicate against + * @hsize: Mode width + * @vsize: Mode height + * @fresh: Mode refresh rate + * @interlaced: Mode interlace support + * + * Walk the CEA mode list looking for a match for the given parameters. + * + * Return: A newly allocated copy of the mode, or NULL if not found. + */ +struct drm_display_mode *drm_mode_find_cea(struct drm_device *dev, int hsize, + int vsize, int fresh, bool interlaced) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(edid_cea_modes_1); i++) { + const struct drm_display_mode *ptr = &edid_cea_modes_1[i]; + + if (hsize != ptr->hdisplay) + continue; + if (vsize != ptr->vdisplay) + continue; + if (fresh != drm_mode_vrefresh(ptr)) + continue; + if (interlaced != (ptr->flags & DRM_MODE_FLAG_INTERLACE)) + continue; + + return drm_mode_duplicate(dev, ptr); + } + + for (i = 0; i < ARRAY_SIZE(edid_cea_modes_193); i++) { + const struct drm_display_mode *ptr = &edid_cea_modes_193[i]; + + if (hsize != ptr->hdisplay) + continue; + if (vsize != ptr->vdisplay) + continue; + if (fresh != drm_mode_vrefresh(ptr)) + continue; + if (interlaced != (ptr->flags & DRM_MODE_FLAG_INTERLACE)) + continue; + + return drm_mode_duplicate(dev, ptr); + } + + return NULL; +} +EXPORT_SYMBOL(drm_mode_find_cea); + /* * drm_mode_find_dmt - Create a copy of a mode if present in DMT * @dev: Device to duplicate against @@ -7345,7 +7396,7 @@ static bool displayid_is_tiled_block(const struct displayid_iter *iter, const struct displayid_block *block) { - return (displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_12 && + return (displayid_version(iter) < DISPLAY_ID_STRUCTURE_VER_20 && block->tag == DATA_BLOCK_TILED_DISPLAY) || (displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_20 && block->tag == DATA_BLOCK_2_TILED_DISPLAY_TOPOLOGY); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_fb_dma_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_fb_dma_helper.c @@ -76,7 +76,6 @@ u8 h_div = 1, v_div = 1; u32 block_w = drm_format_info_block_width(fb->format, plane); u32 block_h = drm_format_info_block_height(fb->format, plane); - u32 block_size = fb->format->char_per_block[plane]; u32 sample_x; u32 sample_y; u32 block_start_y; @@ -99,7 +98,7 @@ num_hblocks = sample_x / block_w; dma_addr += fb->pitches[plane] * block_start_y; - dma_addr += block_size * num_hblocks; + dma_addr += drm_format_plane_width_bytes(fb->format, plane, num_hblocks); return dma_addr; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_fb_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_fb_helper.c @@ -69,7 +69,7 @@ * This module_param *should* be removed as soon as possible and be * considered as a broken and legacy behaviour from a modern fbdev device. */ -static bool drm_leak_fbdev_smem; +static bool drm_leak_fbdev_smem = true; #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM) module_param_unsafe(drm_leak_fbdev_smem, bool, 0600); MODULE_PARM_DESC(drm_leak_fbdev_smem, @@ -524,6 +524,9 @@ if (!info) return ERR_PTR(-ENOMEM); + if (!drm_leak_fbdev_smem) + info->flags |= FBINFO_HIDE_SMEM_START; + ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret) goto err_release; @@ -1860,9 +1863,6 @@ info = fb_helper->info; info->var.pixclock = 0; - if (!drm_leak_fbdev_smem) - info->flags |= FBINFO_HIDE_SMEM_START; - /* Need to drop locks to avoid recursive deadlock in * register_framebuffer. This is ok because the only thing left to do is * register the fbdev emulation instance in kernel_fb_helper_list. */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_fbdev_dma.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_fbdev_dma.c @@ -130,7 +130,10 @@ info->flags |= FBINFO_READS_FAST; /* signal caching */ info->screen_size = sizes->surface_height * fb->pitches[0]; info->screen_buffer = map.vaddr; - info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); + if (!(info->flags & FBINFO_HIDE_SMEM_START)) { + if (!drm_WARN_ON(dev, is_vmalloc_addr(info->screen_buffer))) + info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer)); + } info->fix.smem_len = info->screen_size; return 0; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_fbdev_generic.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_fbdev_generic.c @@ -84,7 +84,8 @@ sizes->surface_width, sizes->surface_height, sizes->surface_bpp); - format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); + format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, + sizes->surface_depth); buffer = drm_client_framebuffer_create(client, sizes->surface_width, sizes->surface_height, format); if (IS_ERR(buffer)) @@ -113,7 +114,6 @@ /* screen */ info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; info->screen_buffer = screen_buffer; - info->fix.smem_start = page_to_phys(vmalloc_to_page(info->screen_buffer)); info->fix.smem_len = screen_size; /* deferred I/O */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_file.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_file.c @@ -469,14 +469,12 @@ dev = filp->minor->dev; mutex_lock(&dev->filelist_mutex); + get_pid(pid); old = rcu_replace_pointer(filp->pid, pid, 1); mutex_unlock(&dev->filelist_mutex); - if (pid != old) { - get_pid(pid); - synchronize_rcu(); - put_pid(old); - } + synchronize_rcu(); + put_pid(old); } /** --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_fourcc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_fourcc.c @@ -29,6 +29,7 @@ #include #include +#include /** * drm_mode_legacy_fb_format - compute drm fourcc code from legacy description @@ -245,6 +246,9 @@ { .format = DRM_FORMAT_NV61, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_NV24, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_NV42, .depth = 0, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true }, + { .format = DRM_FORMAT_XV15, .depth = 0, .num_planes = 2, .pixels_per_macropixel = { 3, 3, 0 }, .bytes_per_macropixel = { 4, 8, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true}, + { .format = DRM_FORMAT_XV20, .depth = 0, .num_planes = 2, .pixels_per_macropixel = { 3, 3, 0 }, .bytes_per_macropixel = { 4, 8, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true}, + { .format = DRM_FORMAT_X403, .depth = 0, .num_planes = 3, .pixels_per_macropixel = { 3, 3, 3 }, .bytes_per_macropixel = { 4, 4, 4 }, .hsub = 1, .vsub = 1, .is_yuv = true}, { .format = DRM_FORMAT_YUYV, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_YVYU, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, { .format = DRM_FORMAT_UYVY, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true }, @@ -318,6 +322,11 @@ { .format = DRM_FORMAT_P030, .depth = 0, .num_planes = 2, .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true}, + { .format = DRM_FORMAT_AVUY, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, + { .format = DRM_FORMAT_XVUY8888, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, + { .format = DRM_FORMAT_XVUY2101010, .depth = 0, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, + { .format = DRM_FORMAT_Y8, .depth = 0, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 }, + { .format = DRM_FORMAT_Y10, .depth = 0, .num_planes = 1, .pixels_per_macropixel = { 3, 0, 0 }, .bytes_per_macropixel = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, }; unsigned int i; @@ -456,3 +465,36 @@ drm_format_info_block_height(info, plane)); } EXPORT_SYMBOL(drm_format_info_min_pitch); + +/** + * drm_format_plane_width_bytes - bytes of the given width of the plane + * @info: DRM format information + * @plane: plane index + * @width: width to get the number of bytes + * + * This returns the number of bytes for given @width and @plane. + * The @char_per_block or macro pixel information should be valid. + * + * Returns: + * The bytes of @width of @plane. 0 for invalid format info. + */ +uint64_t drm_format_plane_width_bytes(const struct drm_format_info *info, + int plane, unsigned int width) +{ + if (!info || plane >= info->num_planes) + return 0; + + if (info->char_per_block[plane]) + return drm_format_info_min_pitch(info, plane, width); + + if (WARN_ON(!info->bytes_per_macropixel[plane] || + !info->pixels_per_macropixel[plane])) { + DRM_WARN("Either cpp or macro-pixel info should be valid: %p4cc\n", + &info->format); + return 0; + } + + return DIV_ROUND_UP(width * info->bytes_per_macropixel[plane], + info->pixels_per_macropixel[plane]); +} +EXPORT_SYMBOL(drm_format_plane_width_bytes); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_framebuffer.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_framebuffer.c @@ -180,7 +180,8 @@ for (i = 0; i < info->num_planes; i++) { unsigned int width = drm_format_info_plane_width(info, r->width, i); unsigned int height = drm_format_info_plane_height(info, r->height, i); - unsigned int block_size = info->char_per_block[i]; + unsigned int block_size = info->char_per_block[i] || + info->bytes_per_macropixel[i]; u64 min_pitch = drm_format_info_min_pitch(info, i, width); if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) { @@ -274,7 +275,8 @@ struct drm_framebuffer *fb; int ret; - if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) { + if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS | + DRM_MODE_FB_ALTERNATE_TOP | DRM_MODE_FB_ALTERNATE_BOTTOM)) { drm_dbg_kms(dev, "bad framebuffer flags 0x%08x\n", r->flags); return ERR_PTR(-EINVAL); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_gem_atomic_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -224,8 +224,8 @@ __drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base); - drm_format_conv_state_copy(&shadow_plane_state->fmtcnv_state, - &new_shadow_plane_state->fmtcnv_state); + drm_format_conv_state_copy(&new_shadow_plane_state->fmtcnv_state, + &shadow_plane_state->fmtcnv_state); } EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_gem_shmem_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -610,6 +610,9 @@ return ret; } + if (is_cow_mapping(vma->vm_flags)) + return -EINVAL; + dma_resv_lock(shmem->base.resv, NULL); ret = drm_gem_shmem_get_pages(shmem); dma_resv_unlock(shmem->base.resv); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_mipi_dsi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_mipi_dsi.c @@ -654,7 +654,7 @@ * * Return: 0 on success or a negative error code on failure. */ -ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) +int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable) { /* Note: Needs updating for non-default PPS or algorithm */ u8 tx[2] = { enable << 0, 0 }; @@ -679,8 +679,8 @@ * * Return: 0 on success or a negative error code on failure. */ -ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, - const struct drm_dsc_picture_parameter_set *pps) +int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, + const struct drm_dsc_picture_parameter_set *pps) { struct mipi_dsi_msg msg = { .channel = dsi->channel, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_modeset_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_modeset_helper.c @@ -193,13 +193,22 @@ if (!dev) return 0; + /* + * Don't disable polling if it was never initialized + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_disable(dev); - drm_kms_helper_poll_disable(dev); drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1); state = drm_atomic_helper_suspend(dev); if (IS_ERR(state)) { drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); - drm_kms_helper_poll_enable(dev); + /* + * Don't enable polling if it was never initialized + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_enable(dev); + return PTR_ERR(state); } @@ -239,7 +248,11 @@ dev->mode_config.suspend_state = NULL; drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); - drm_kms_helper_poll_enable(dev); + /* + * Don't enable polling if it is not initialized + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_enable(dev); return ret; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_panel.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_panel.c @@ -274,19 +274,24 @@ * The modes probed from the panel are automatically added to the connector * that the panel is attached to. * - * Return: The number of modes available from the panel on success or a - * negative error code on failure. + * Return: The number of modes available from the panel on success, or 0 on + * failure (no modes). */ int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { if (!panel) - return -EINVAL; + return 0; - if (panel->funcs && panel->funcs->get_modes) - return panel->funcs->get_modes(panel, connector); + if (panel->funcs && panel->funcs->get_modes) { + int num; - return -EOPNOTSUPP; + num = panel->funcs->get_modes(panel, connector); + if (num > 0) + return num; + } + + return 0; } EXPORT_SYMBOL(drm_panel_get_modes); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -117,6 +117,12 @@ .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, }; +static const struct drm_dmi_panel_orientation_data lcd1080x1920_rightside_up = { + .width = 1080, + .height = 1920, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = { .width = 1200, .height = 1920, @@ -196,6 +202,12 @@ DMI_MATCH(DMI_BOARD_NAME, "NEXT"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* AYA NEO KUN */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_MATCH(DMI_BOARD_NAME, "KUN"), + }, + .driver_data = (void *)&lcd1600x2560_rightside_up, }, { /* Chuwi HiBook (CWI514) */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), @@ -279,6 +291,12 @@ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03") }, .driver_data = (void *)&lcd720x1280_rightside_up, + }, { /* GPD Win Mini */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1617-01") + }, + .driver_data = (void *)&lcd1080x1920_rightside_up, }, { /* I.T.Works TW891 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), @@ -409,6 +427,13 @@ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Valve Steam Deck */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_prime.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_prime.c @@ -582,7 +582,12 @@ { struct drm_gem_object *obj = dma_buf->priv; - if (!obj->funcs->get_sg_table) + /* + * drm_gem_map_dma_buf() requires obj->get_sg_table(), but drivers + * that implement their own ->map_dma_buf() do not. + */ + if (dma_buf->ops->map_dma_buf == drm_gem_map_dma_buf && + !obj->funcs->get_sg_table) return -ENOSYS; return drm_gem_pin(obj); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/drm_probe_helper.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/drm_probe_helper.c @@ -293,14 +293,17 @@ * Drivers can call this helper from their device resume implementation. It is * not an error to call this even when output polling isn't enabled. * + * If device polling was never initialized before, this call will trigger a + * warning and return. + * * Note that calls to enable and disable polling must be strictly ordered, which * is automatically the case when they're only call from suspend/resume * callbacks. */ void drm_kms_helper_poll_enable(struct drm_device *dev) { - if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll || - dev->mode_config.poll_running) + if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) || + !drm_kms_helper_poll || dev->mode_config.poll_running) return; if (drm_kms_helper_enable_hpd(dev) || @@ -419,6 +422,13 @@ count = connector_funcs->get_modes(connector); + /* The .get_modes() callback should not return negative values. */ + if (count < 0) { + drm_err(connector->dev, ".get_modes() returned %pe\n", + ERR_PTR(count)); + count = 0; + } + /* * Fallback for when DDC probe failed in drm_get_edid() and thus skipped * override/firmware EDID. @@ -619,8 +629,12 @@ 0); } - /* Re-enable polling in case the global poll config changed. */ - drm_kms_helper_poll_enable(dev); + /* + * Re-enable polling in case the global poll config changed but polling + * is still initialized. + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_enable(dev); if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", @@ -873,12 +887,18 @@ * not an error to call this even when output polling isn't enabled or already * disabled. Polling is re-enabled by calling drm_kms_helper_poll_enable(). * + * If however, the polling was never initialized, this call will trigger a + * warning and return + * * Note that calls to enable and disable polling must be strictly ordered, which * is automatically the case when they're only call from suspend/resume * callbacks. */ void drm_kms_helper_poll_disable(struct drm_device *dev) { + if (drm_WARN_ON(dev, !dev->mode_config.poll_enabled)) + return; + if (dev->mode_config.poll_running) drm_kms_helper_disable_hpd(dev); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -494,7 +494,7 @@ .desc = "etnaviv DRM", .date = "20151214", .major = 1, - .minor = 3, + .minor = 4, }; /* --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -632,8 +632,8 @@ /* Disable TX clock gating on affected core revisions. */ if (etnaviv_is_model_rev(gpu, GC4000, 0x5222) || etnaviv_is_model_rev(gpu, GC2000, 0x5108) || - etnaviv_is_model_rev(gpu, GC2000, 0x6202) || - etnaviv_is_model_rev(gpu, GC2000, 0x6203)) + etnaviv_is_model_rev(gpu, GC7000, 0x6202) || + etnaviv_is_model_rev(gpu, GC7000, 0x6203)) pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX; /* Disable SE and RA clock gating on affected core revisions. */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c @@ -265,6 +265,9 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu) { struct etnaviv_chip_identity *ident = &gpu->identity; + const u32 product_id = ident->product_id; + const u32 customer_id = ident->customer_id; + const u32 eco_id = ident->eco_id; int i; for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) { @@ -278,6 +281,12 @@ etnaviv_chip_identities[i].eco_id == ~0U)) { memcpy(ident, &etnaviv_chip_identities[i], sizeof(*ident)); + + /* Restore some id values as ~0U aka 'don't care' might been used. */ + ident->product_id = product_id; + ident->customer_id = customer_id; + ident->eco_id = eco_id; + return true; } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/exynos/exynos_dp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/exynos/exynos_dp.c @@ -286,7 +286,6 @@ .remove_new = exynos_dp_remove, .driver = { .name = "exynos-dp", - .owner = THIS_MODULE, .pm = pm_ptr(&exynos_dp_pm_ops), .of_match_table = exynos_dp_match, }, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -309,6 +309,7 @@ struct vidi_context *ctx = ctx_from_connector(connector); struct edid *edid; int edid_len; + int count; /* * the edid data comes from user side and it would be set @@ -316,19 +317,23 @@ */ if (!ctx->raw_edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); - return -EFAULT; + return 0; } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); - return -ENOMEM; + return 0; } drm_connector_update_edid_property(connector, edid); - return drm_add_edid_modes(connector, edid); + count = drm_add_edid_modes(connector, edid); + + kfree(edid); + + return count; } static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/exynos/exynos_hdmi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -887,11 +887,11 @@ int ret; if (!hdata->ddc_adpt) - return -ENODEV; + goto no_edid; edid = drm_get_edid(connector, hdata->ddc_adpt); if (!edid) - return -ENODEV; + goto no_edid; hdata->dvi_mode = !connector->display_info.is_hdmi; DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n", @@ -906,6 +906,9 @@ kfree(edid); return ret; + +no_edid: + return drm_add_modes_noedid(connector, 640, 480); } static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/gma500/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/gma500/Makefile @@ -34,7 +34,6 @@ psb_intel_lvds.o \ psb_intel_modes.o \ psb_intel_sdvo.o \ - psb_lid.o \ psb_irq.o gma500_gfx-$(CONFIG_ACPI) += opregion.o --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/gma500/psb_device.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/gma500/psb_device.c @@ -73,8 +73,7 @@ } psb_intel_lvds_set_brightness(dev, PSB_MAX_BRIGHTNESS); - /* This must occur after the backlight is properly initialised */ - psb_lid_timer_init(dev_priv); + return 0; } @@ -259,8 +258,6 @@ static void psb_chip_teardown(struct drm_device *dev) { - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - psb_lid_timer_takedown(dev_priv); gma_intel_teardown_gmbus(dev); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/gma500/psb_drv.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/gma500/psb_drv.h @@ -162,7 +162,6 @@ #define PSB_NUM_VBLANKS 2 #define PSB_WATCHDOG_DELAY (HZ * 2) -#define PSB_LID_DELAY (HZ / 10) #define PSB_MAX_BRIGHTNESS 100 @@ -491,11 +490,7 @@ /* Hotplug handling */ struct work_struct hotplug_work; - /* LID-Switch */ - spinlock_t lid_lock; - struct timer_list lid_timer; struct psb_intel_opregion opregion; - u32 lid_last_state; /* Watchdog */ uint32_t apm_reg; @@ -591,10 +586,6 @@ int i2c_bus; /* I2C bus identifier for Moorestown */ }; -/* psb_lid.c */ -extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); -extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv); - /* modesetting */ extern void psb_modeset_init(struct drm_device *dev); extern void psb_modeset_cleanup(struct drm_device *dev); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/Makefile @@ -33,9 +33,9 @@ subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror # Fine grained warnings disable -CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init) -CFLAGS_display/intel_display_device.o = $(call cc-disable-warning, override-init) -CFLAGS_display/intel_fbdev.o = $(call cc-disable-warning, override-init) +CFLAGS_i915_pci.o = -Wno-override-init +CFLAGS_display/intel_display_device.o = -Wno-override-init +CFLAGS_display/intel_fbdev.o = -Wno-override-init # Support compiling the display code separately for both i915 and xe # drivers. Define I915 when building i915. @@ -118,6 +118,7 @@ gt/intel_ggtt_fencing.o \ gt/intel_gt.o \ gt/intel_gt_buffer_pool.o \ + gt/intel_gt_ccs_mode.o \ gt/intel_gt_clock_utils.o \ gt/intel_gt_debugfs.o \ gt/intel_gt_engines_debugfs.o \ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/g4x_dp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/g4x_dp.c @@ -717,7 +717,6 @@ { intel_enable_dp(state, encoder, pipe_config, conn_state); intel_edp_backlight_on(pipe_config, conn_state); - encoder->audio_enable(encoder, pipe_config, conn_state); } static void vlv_enable_dp(struct intel_atomic_state *state, @@ -726,7 +725,6 @@ const struct drm_connector_state *conn_state) { intel_edp_backlight_on(pipe_config, conn_state); - encoder->audio_enable(encoder, pipe_config, conn_state); } static void g4x_pre_enable_dp(struct intel_atomic_state *state, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/icl_dsi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1155,7 +1155,6 @@ } intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); - intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); /* ensure all panel commands dispatched before enabling transcoder */ wait_for_cmds_dispatched_to_panel(encoder); @@ -1256,6 +1255,8 @@ /* step6d: enable dsi transcoder */ gen11_dsi_enable_transcoder(encoder); + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON); + /* step7: enable backlight */ intel_backlight_enable(crtc_state, conn_state); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_audio.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_audio.c @@ -76,19 +76,6 @@ struct intel_crtc_state *crtc_state); }; -/* DP N/M table */ -#define LC_810M 810000 -#define LC_540M 540000 -#define LC_270M 270000 -#define LC_162M 162000 - -struct dp_aud_n_m { - int sample_rate; - int clock; - u16 m; - u16 n; -}; - struct hdmi_aud_ncts { int sample_rate; int clock; @@ -96,60 +83,6 @@ int cts; }; -/* Values according to DP 1.4 Table 2-104 */ -static const struct dp_aud_n_m dp_aud_n_m[] = { - { 32000, LC_162M, 1024, 10125 }, - { 44100, LC_162M, 784, 5625 }, - { 48000, LC_162M, 512, 3375 }, - { 64000, LC_162M, 2048, 10125 }, - { 88200, LC_162M, 1568, 5625 }, - { 96000, LC_162M, 1024, 3375 }, - { 128000, LC_162M, 4096, 10125 }, - { 176400, LC_162M, 3136, 5625 }, - { 192000, LC_162M, 2048, 3375 }, - { 32000, LC_270M, 1024, 16875 }, - { 44100, LC_270M, 784, 9375 }, - { 48000, LC_270M, 512, 5625 }, - { 64000, LC_270M, 2048, 16875 }, - { 88200, LC_270M, 1568, 9375 }, - { 96000, LC_270M, 1024, 5625 }, - { 128000, LC_270M, 4096, 16875 }, - { 176400, LC_270M, 3136, 9375 }, - { 192000, LC_270M, 2048, 5625 }, - { 32000, LC_540M, 1024, 33750 }, - { 44100, LC_540M, 784, 18750 }, - { 48000, LC_540M, 512, 11250 }, - { 64000, LC_540M, 2048, 33750 }, - { 88200, LC_540M, 1568, 18750 }, - { 96000, LC_540M, 1024, 11250 }, - { 128000, LC_540M, 4096, 33750 }, - { 176400, LC_540M, 3136, 18750 }, - { 192000, LC_540M, 2048, 11250 }, - { 32000, LC_810M, 1024, 50625 }, - { 44100, LC_810M, 784, 28125 }, - { 48000, LC_810M, 512, 16875 }, - { 64000, LC_810M, 2048, 50625 }, - { 88200, LC_810M, 1568, 28125 }, - { 96000, LC_810M, 1024, 16875 }, - { 128000, LC_810M, 4096, 50625 }, - { 176400, LC_810M, 3136, 28125 }, - { 192000, LC_810M, 2048, 16875 }, -}; - -static const struct dp_aud_n_m * -audio_config_dp_get_n_m(const struct intel_crtc_state *crtc_state, int rate) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) { - if (rate == dp_aud_n_m[i].sample_rate && - crtc_state->port_clock == dp_aud_n_m[i].clock) - return &dp_aud_n_m[i]; - } - - return NULL; -} - static const struct { int clock; u32 config; @@ -387,47 +320,17 @@ const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); - struct i915_audio_component *acomp = i915->display.audio.component; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - enum port port = encoder->port; - const struct dp_aud_n_m *nm; - int rate; - u32 tmp; - - rate = acomp ? acomp->aud_sample_rate[port] : 0; - nm = audio_config_dp_get_n_m(crtc_state, rate); - if (nm) - drm_dbg_kms(&i915->drm, "using Maud %u, Naud %u\n", nm->m, - nm->n); - else - drm_dbg_kms(&i915->drm, "using automatic Maud, Naud\n"); - - tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder)); - tmp &= ~AUD_CONFIG_N_VALUE_INDEX; - tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; - tmp &= ~AUD_CONFIG_N_PROG_ENABLE; - tmp |= AUD_CONFIG_N_VALUE_INDEX; - - if (nm) { - tmp &= ~AUD_CONFIG_N_MASK; - tmp |= AUD_CONFIG_N(nm->n); - tmp |= AUD_CONFIG_N_PROG_ENABLE; - } - - intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp); - - tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder)); - tmp &= ~AUD_CONFIG_M_MASK; - tmp &= ~AUD_M_CTS_M_VALUE_INDEX; - tmp &= ~AUD_M_CTS_M_PROG_ENABLE; - if (nm) { - tmp |= nm->m; - tmp |= AUD_M_CTS_M_VALUE_INDEX; - tmp |= AUD_M_CTS_M_PROG_ENABLE; - } + /* Enable time stamps. Let HW calculate Maud/Naud values */ + intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder), + AUD_CONFIG_N_VALUE_INDEX | + AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK | + AUD_CONFIG_UPPER_N_MASK | + AUD_CONFIG_LOWER_N_MASK | + AUD_CONFIG_N_PROG_ENABLE, + AUD_CONFIG_N_VALUE_INDEX); - intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp); } static void @@ -1349,17 +1252,6 @@ static void i915_audio_component_init(struct drm_i915_private *i915) { u32 aud_freq, aud_freq_init; - int ret; - - ret = component_add_typed(i915->drm.dev, - &i915_audio_component_bind_ops, - I915_COMPONENT_AUDIO); - if (ret < 0) { - drm_err(&i915->drm, - "failed to add audio component (%d)\n", ret); - /* continue with reduced functionality */ - return; - } if (DISPLAY_VER(i915) >= 9) { aud_freq_init = intel_de_read(i915, AUD_FREQ_CNTRL); @@ -1382,6 +1274,21 @@ /* init with current cdclk */ intel_audio_cdclk_change_post(i915); +} + +static void i915_audio_component_register(struct drm_i915_private *i915) +{ + int ret; + + ret = component_add_typed(i915->drm.dev, + &i915_audio_component_bind_ops, + I915_COMPONENT_AUDIO); + if (ret < 0) { + drm_err(&i915->drm, + "failed to add audio component (%d)\n", ret); + /* continue with reduced functionality */ + return; + } i915->display.audio.component_registered = true; } @@ -1414,6 +1321,12 @@ i915_audio_component_init(i915); } +void intel_audio_register(struct drm_i915_private *i915) +{ + if (!i915->display.audio.lpe.platdev) + i915_audio_component_register(i915); +} + /** * intel_audio_deinit() - deinitialize the audio driver * @i915: the i915 drm device private data --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_audio.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_audio.h @@ -28,6 +28,7 @@ void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); void intel_audio_init(struct drm_i915_private *dev_priv); +void intel_audio_register(struct drm_i915_private *i915); void intel_audio_deinit(struct drm_i915_private *dev_priv); void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_bios.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_bios.c @@ -1042,22 +1042,11 @@ panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; panel->vbt.backlight.controller = 0; if (i915->display.vbt.version >= 191) { - size_t exp_size; + const struct lfp_backlight_control_method *method; - if (i915->display.vbt.version >= 236) - exp_size = sizeof(struct bdb_lfp_backlight_data); - else if (i915->display.vbt.version >= 234) - exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234; - else - exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191; - - if (get_blocksize(backlight_data) >= exp_size) { - const struct lfp_backlight_control_method *method; - - method = &backlight_data->backlight_control[panel_type]; - panel->vbt.backlight.type = method->type; - panel->vbt.backlight.controller = method->controller; - } + method = &backlight_data->backlight_control[panel_type]; + panel->vbt.backlight.type = method->type; + panel->vbt.backlight.controller = method->controller; } panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; @@ -1952,16 +1941,12 @@ * these devices we split the init OTP sequence into a deassert sequence and * the actual init OTP part. */ -static void fixup_mipi_sequences(struct drm_i915_private *i915, - struct intel_panel *panel) +static void vlv_fixup_mipi_sequences(struct drm_i915_private *i915, + struct intel_panel *panel) { u8 *init_otp; int len; - /* Limit this to VLV for now. */ - if (!IS_VALLEYVIEW(i915)) - return; - /* Limit this to v1 vid-mode sequences */ if (panel->vbt.dsi.config->is_cmd_mode || panel->vbt.dsi.seq_version != 1) @@ -1997,6 +1982,41 @@ panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1; } +/* + * Some machines (eg. Lenovo 82TQ) appear to have broken + * VBT sequences: + * - INIT_OTP is not present at all + * - what should be in INIT_OTP is in DISPLAY_ON + * - what should be in DISPLAY_ON is in BACKLIGHT_ON + * (along with the actual backlight stuff) + * + * To make those work we simply swap DISPLAY_ON and INIT_OTP. + * + * TODO: Do we need to limit this to specific machines, + * or examine the contents of the sequences to + * avoid false positives? + */ +static void icl_fixup_mipi_sequences(struct drm_i915_private *i915, + struct intel_panel *panel) +{ + if (!panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] && + panel->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]) { + drm_dbg_kms(&i915->drm, "Broken VBT: Swapping INIT_OTP and DISPLAY_ON sequences\n"); + + swap(panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP], + panel->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]); + } +} + +static void fixup_mipi_sequences(struct drm_i915_private *i915, + struct intel_panel *panel) +{ + if (DISPLAY_VER(i915) >= 11) + icl_fixup_mipi_sequences(i915, panel); + else if (IS_VALLEYVIEW(i915)) + vlv_fixup_mipi_sequences(i915, panel); +} + static void parse_mipi_sequence(struct drm_i915_private *i915, struct intel_panel *panel) @@ -3344,6 +3364,9 @@ { const struct child_device_config *child = &devdata->child; + if (!devdata) + return false; + if (!intel_bios_encoder_supports_dp(devdata) || !intel_bios_encoder_supports_hdmi(devdata)) return false; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_bw.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_bw.c @@ -162,7 +162,9 @@ 1); if (ret < 0) { - drm_err(&dev_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask); + drm_err(&dev_priv->drm, + "Failed to disable qgv points (0x%x) points: 0x%x\n", + ret, points_mask); return ret; } @@ -290,8 +292,10 @@ struct intel_qgv_point *sp = &qi->points[i]; ret = intel_read_qgv_point_info(dev_priv, sp, i); - if (ret) + if (ret) { + drm_dbg_kms(&dev_priv->drm, "Could not read QGV %d info\n", i); return ret; + } drm_dbg_kms(&dev_priv->drm, "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", @@ -659,6 +663,22 @@ return bi->psf_bw[psf_gv_point]; } +static unsigned int icl_qgv_bw(struct drm_i915_private *i915, + int num_active_planes, int qgv_point) +{ + unsigned int idx; + + if (DISPLAY_VER(i915) >= 12) + idx = tgl_max_bw_index(i915, num_active_planes, qgv_point); + else + idx = icl_max_bw_index(i915, num_active_planes, qgv_point); + + if (idx >= ARRAY_SIZE(i915->display.bw.max)) + return 0; + + return i915->display.bw.max[idx].deratedbw[qgv_point]; +} + void intel_bw_init_hw(struct drm_i915_private *dev_priv) { if (!HAS_DISPLAY(dev_priv)) @@ -735,6 +755,7 @@ intel_bw_crtc_data_rate(crtc_state); bw_state->num_active_planes[crtc->pipe] = intel_bw_crtc_num_active_planes(crtc_state); + bw_state->force_check_qgv = true; drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n", pipe_name(crtc->pipe), @@ -804,6 +825,80 @@ return to_intel_bw_state(bw_state); } +static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, + int num_active_planes) +{ + unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int max_bw_point = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_qgv_points; i++) { + unsigned int max_data_rate = + icl_qgv_bw(i915, num_active_planes, i); + + /* + * We need to know which qgv point gives us + * maximum bandwidth in order to disable SAGV + * if we find that we exceed SAGV block time + * with watermarks. By that moment we already + * have those, as it is calculated earlier in + * intel_atomic_check, + */ + if (max_data_rate > max_bw) { + max_bw_point = BIT(i); + max_bw = max_data_rate; + } + } + + return max_bw_point; +} + +static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, + unsigned int qgv_points, + unsigned int psf_points) +{ + return ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | + ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); +} + +static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) +{ + unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int max_bw_point_mask = 0; + unsigned int max_bw = 0; + int i; + + for (i = 0; i < num_psf_gv_points; i++) { + unsigned int max_data_rate = adl_psf_bw(i915, i); + + if (max_data_rate > max_bw) { + max_bw_point_mask = BIT(i); + max_bw = max_data_rate; + } else if (max_data_rate == max_bw) { + max_bw_point_mask |= BIT(i); + } + } + + return max_bw_point_mask; +} + +static void icl_force_disable_sagv(struct drm_i915_private *i915, + struct intel_bw_state *bw_state) +{ + unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0); + unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915); + + bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + qgv_points, + psf_points); + + drm_dbg_kms(&i915->drm, "Forcing SAGV disable: mask 0x%x\n", + bw_state->qgv_points_mask); + + icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask); +} + static int mtl_find_qgv_points(struct drm_i915_private *i915, unsigned int data_rate, unsigned int num_active_planes, @@ -881,8 +976,6 @@ const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int max_bw_point = 0; - unsigned int max_bw = 0; unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; u16 psf_points = 0; @@ -895,31 +988,8 @@ return ret; for (i = 0; i < num_qgv_points; i++) { - unsigned int idx; - unsigned int max_data_rate; - - if (DISPLAY_VER(i915) >= 12) - idx = tgl_max_bw_index(i915, num_active_planes, i); - else - idx = icl_max_bw_index(i915, num_active_planes, i); - - if (idx >= ARRAY_SIZE(i915->display.bw.max)) - continue; - - max_data_rate = i915->display.bw.max[idx].deratedbw[i]; - - /* - * We need to know which qgv point gives us - * maximum bandwidth in order to disable SAGV - * if we find that we exceed SAGV block time - * with watermarks. By that moment we already - * have those, as it is calculated earlier in - * intel_atomic_check, - */ - if (max_data_rate > max_bw) { - max_bw_point = i; - max_bw = max_data_rate; - } + unsigned int max_data_rate = icl_qgv_bw(i915, + num_active_planes, i); if (max_data_rate >= data_rate) qgv_points |= BIT(i); @@ -963,20 +1033,18 @@ * cause. */ if (!intel_can_enable_sagv(i915, new_bw_state)) { - qgv_points = BIT(max_bw_point); - drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point %d\n", - max_bw_point); + qgv_points = icl_max_bw_qgv_point_mask(i915, num_active_planes); + drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point mask 0x%x\n", + qgv_points); } /* * We store the ones which need to be masked as that is what PCode * actually accepts as a parameter. */ - new_bw_state->qgv_points_mask = - ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | - ADLS_PCODE_REQ_PSF_PT(psf_points)) & - icl_qgv_points_mask(i915); - + new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + qgv_points, + psf_points); /* * If the actual mask had changed we need to make sure that * the commits are serialized(in case this is a nomodeset, nonblocking) @@ -1272,8 +1340,9 @@ new_bw_state = intel_atomic_get_new_bw_state(state); if (new_bw_state && - intel_can_enable_sagv(i915, old_bw_state) != - intel_can_enable_sagv(i915, new_bw_state)) + (intel_can_enable_sagv(i915, old_bw_state) != + intel_can_enable_sagv(i915, new_bw_state) || + new_bw_state->force_check_qgv)) changed = true; /* @@ -1287,6 +1356,8 @@ if (ret) return ret; + new_bw_state->force_check_qgv = false; + return 0; } @@ -1313,7 +1384,7 @@ .atomic_destroy_state = intel_bw_destroy_state, }; -int intel_bw_init(struct drm_i915_private *dev_priv) +int intel_bw_init(struct drm_i915_private *i915) { struct intel_bw_state *state; @@ -1321,8 +1392,15 @@ if (!state) return -ENOMEM; - intel_atomic_global_obj_init(dev_priv, &dev_priv->display.bw.obj, + intel_atomic_global_obj_init(i915, &i915->display.bw.obj, &state->base, &intel_bw_funcs); + /* + * Limit this only if we have SAGV. And for Display version 14 onwards + * sagv is handled though pmdemand requests + */ + if (intel_has_sagv(i915) && IS_DISPLAY_VER(i915, 11, 13)) + icl_force_disable_sagv(i915, state); + return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_bw.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_bw.h @@ -47,6 +47,12 @@ */ u16 qgv_points_mask; + /* + * Flag to force the QGV comparison in atomic check right after the + * hw state readout + */ + bool force_check_qgv; + int min_cdclk[I915_MAX_PIPES]; unsigned int data_rate[I915_MAX_PIPES]; u8 num_active_planes[I915_MAX_PIPES]; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cdclk.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -2512,7 +2512,8 @@ intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = intel_atomic_get_new_cdclk_state(state); - enum pipe pipe = new_cdclk_state->pipe; + struct intel_cdclk_config cdclk_config; + enum pipe pipe; if (!intel_cdclk_changed(&old_cdclk_state->actual, &new_cdclk_state->actual)) @@ -2521,12 +2522,25 @@ if (IS_DG2(i915)) intel_cdclk_pcode_pre_notify(state); - if (pipe == INVALID_PIPE || - old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) { - drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed); + if (new_cdclk_state->disable_pipes) { + cdclk_config = new_cdclk_state->actual; + pipe = INVALID_PIPE; + } else { + if (new_cdclk_state->actual.cdclk >= old_cdclk_state->actual.cdclk) { + cdclk_config = new_cdclk_state->actual; + pipe = new_cdclk_state->pipe; + } else { + cdclk_config = old_cdclk_state->actual; + pipe = INVALID_PIPE; + } - intel_set_cdclk(i915, &new_cdclk_state->actual, pipe); + cdclk_config.voltage_level = max(new_cdclk_state->actual.voltage_level, + old_cdclk_state->actual.voltage_level); } + + drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed); + + intel_set_cdclk(i915, &cdclk_config, pipe); } /** @@ -2544,7 +2558,7 @@ intel_atomic_get_old_cdclk_state(state); const struct intel_cdclk_state *new_cdclk_state = intel_atomic_get_new_cdclk_state(state); - enum pipe pipe = new_cdclk_state->pipe; + enum pipe pipe; if (!intel_cdclk_changed(&old_cdclk_state->actual, &new_cdclk_state->actual)) @@ -2553,12 +2567,15 @@ if (IS_DG2(i915)) intel_cdclk_pcode_post_notify(state); - if (pipe != INVALID_PIPE && - old_cdclk_state->actual.cdclk > new_cdclk_state->actual.cdclk) { - drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed); + if (!new_cdclk_state->disable_pipes && + new_cdclk_state->actual.cdclk < old_cdclk_state->actual.cdclk) + pipe = new_cdclk_state->pipe; + else + pipe = INVALID_PIPE; - intel_set_cdclk(i915, &new_cdclk_state->actual, pipe); - } + drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed); + + intel_set_cdclk(i915, &new_cdclk_state->actual, pipe); } static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state) @@ -3036,6 +3053,7 @@ return NULL; cdclk_state->pipe = INVALID_PIPE; + cdclk_state->disable_pipes = false; return &cdclk_state->base; } @@ -3214,6 +3232,8 @@ if (ret) return ret; + new_cdclk_state->disable_pipes = true; + drm_dbg_kms(&dev_priv->drm, "Modeset required for cdclk change\n"); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cdclk.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_cdclk.h @@ -51,6 +51,9 @@ /* bitmask of active pipes */ u8 active_pipes; + + /* update cdclk with pipes disabled */ + bool disable_pipes; }; int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cursor.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_cursor.c @@ -35,12 +35,10 @@ { struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev); - const struct drm_framebuffer *fb = plane_state->hw.fb; - struct drm_i915_gem_object *obj = intel_fb_obj(fb); u32 base; if (DISPLAY_INFO(dev_priv)->cursor_needs_physical) - base = i915_gem_object_get_dma_address(obj, 0); + base = plane_state->phys_dma_addr; else base = intel_plane_ggtt_offset(plane_state); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_ddi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4229,7 +4229,12 @@ static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state1, const struct intel_crtc_state *crtc_state2) { + /* + * FIXME the modeset sequence is currently wrong and + * can't deal with bigjoiner + port sync at the same time. + */ return crtc_state1->hw.active && crtc_state2->hw.active && + !crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes && crtc_state1->output_types == crtc_state2->output_types && crtc_state1->output_format == crtc_state2->output_format && crtc_state1->lane_count == crtc_state2->lane_count && --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_device.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_display_device.h @@ -47,6 +47,7 @@ #define HAS_DPT(i915) (DISPLAY_VER(i915) >= 13) #define HAS_DSB(i915) (DISPLAY_INFO(i915)->has_dsb) #define HAS_DSC(__i915) (DISPLAY_RUNTIME_INFO(__i915)->has_dsc) +#define HAS_DSC_MST(__i915) (DISPLAY_VER(__i915) >= 12 && HAS_DSC(__i915)) #define HAS_FBC(i915) (DISPLAY_RUNTIME_INFO(i915)->fbc_mask != 0) #define HAS_FPGA_DBG_UNCLAIMED(i915) (DISPLAY_INFO(i915)->has_fpga_dbg) #define HAS_FW_BLC(i915) (DISPLAY_VER(i915) >= 3) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_driver.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -394,6 +394,8 @@ intel_audio_init(i915); + intel_audio_register(i915); + intel_display_debugfs_register(i915); /* --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_trace.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_display_trace.h @@ -411,7 +411,7 @@ struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), plane->pipe); __assign_str(dev, __dev_name_kms(plane)); - __assign_str(name, plane->base.name) + __assign_str(name, plane->base.name); __entry->pipe = crtc->pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); @@ -438,7 +438,7 @@ struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), plane->pipe); __assign_str(dev, __dev_name_kms(plane)); - __assign_str(name, plane->base.name) + __assign_str(name, plane->base.name); __entry->pipe = crtc->pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); @@ -465,7 +465,7 @@ struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev), plane->pipe); __assign_str(dev, __dev_name_kms(plane)); - __assign_str(name, plane->base.name) + __assign_str(name, plane->base.name); __entry->pipe = crtc->pipe; __entry->frame = intel_crtc_get_vblank_counter(crtc); __entry->scanline = intel_get_crtc_scanline(crtc); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_display_types.h @@ -719,6 +719,7 @@ #define PLANE_HAS_FENCE BIT(0) struct intel_fb_view view; + u32 phys_dma_addr; /* for cursor_needs_physical */ /* Plane pxp decryption state */ bool decrypt; @@ -1715,8 +1716,15 @@ bool psr2_sel_fetch_cff_enabled; bool req_psr2_sdp_prior_scanline; u8 sink_sync_latency; - u8 io_wake_lines; - u8 fast_wake_lines; + + struct { + u8 io_wake_lines; + u8 fast_wake_lines; + + /* LNL and beyond */ + u8 check_entry_lines; + } alpm_parameters; + ktime_t last_entry_attempt; ktime_t last_exit; bool sink_not_reliable; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dp.c @@ -434,6 +434,10 @@ struct intel_encoder *encoder = &intel_dig_port->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + /* eDP MSO is not compatible with joiner */ + if (intel_dp->mso_link_count) + return false; + return DISPLAY_VER(dev_priv) >= 12 || (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A); @@ -1422,7 +1426,8 @@ if (DISPLAY_VER(dev_priv) >= 12) return true; - if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A) + if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A && + !intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST)) return true; return false; @@ -1915,8 +1920,9 @@ dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { - if (valid_dsc_bpp[i] < dsc_min_bpp || - valid_dsc_bpp[i] > dsc_max_bpp) + if (valid_dsc_bpp[i] < dsc_min_bpp) + continue; + if (valid_dsc_bpp[i] > dsc_max_bpp) break; ret = dsc_compute_link_config(intel_dp, @@ -2754,7 +2760,11 @@ intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode); int pixel_clock; - if (has_seamless_m_n(connector)) + /* + * FIXME all joined pipes share the same transcoder. + * Need to account for that when updating M/N live. + */ + if (has_seamless_m_n(connector) && !pipe_config->bigjoiner_pipes) pipe_config->update_m_n = true; if (!can_enable_drrs(connector, pipe_config, downclock_mode)) { @@ -5498,6 +5508,17 @@ return drm_edid_read_ddc(&connector->base, &intel_dp->aux.ddc); } +const struct edid * +intel_dp_fetch_edid(struct intel_dp *intel_dp) +{ + const struct drm_edid * d_edid; + d_edid = intel_dp_get_edid(intel_dp); + if (d_edid) + return drm_edid_raw(d_edid); + + return NULL; +} + static void intel_dp_update_dfp(struct intel_dp *intel_dp, const struct drm_edid *drm_edid) @@ -6523,6 +6544,7 @@ intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; else intel_connector->get_hw_state = intel_connector_get_hw_state; + intel_connector->sync_state = intel_dp_connector_sync_state; if (!intel_edp_init_connector(intel_dp, intel_connector)) { intel_dp_aux_fini(intel_dp); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dp.h @@ -187,4 +187,6 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector); +const struct edid *intel_dp_fetch_edid(struct intel_dp *intel_dp); + #endif /* __INTEL_DP_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -142,9 +142,15 @@ return precharge + preamble; } -static int intel_dp_aux_fw_sync_len(void) +int intel_dp_aux_fw_sync_len(void) { - int precharge = 10; /* 10-16 */ + /* + * We faced some glitches on Dell Precision 5490 MTL laptop with panel: + * "Manufacturer: AUO, Model: 63898" when using HW default 18. Using 20 + * is fixing these problems with the panel. It is still within range + * mentioned in eDP specification. + */ + int precharge = 12; /* 10-16 */ int preamble = 8; return precharge + preamble; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_aux.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dp_aux.h @@ -20,5 +20,6 @@ void intel_dp_aux_irq_handler(struct drm_i915_private *i915); u32 intel_dp_aux_pack(const u8 *src, int src_bytes); +int intel_dp_aux_fw_sync_len(void); #endif /* __INTEL_DP_AUX_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1148,7 +1148,7 @@ if (first_mst_stream) intel_ddi_wait_for_fec_status(encoder, pipe_config, true); - drm_dp_add_payload_part2(&intel_dp->mst_mgr, &state->base, + drm_dp_add_payload_part2(&intel_dp->mst_mgr, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (DISPLAY_VER(dev_priv) >= 12) @@ -1338,7 +1338,7 @@ return 0; } - if (DISPLAY_VER(dev_priv) >= 10 && + if (HAS_DSC_MST(dev_priv) && drm_dp_sink_supports_dsc(intel_connector->dp.dsc_dpcd)) { /* * TBD pass the connector BPC, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -2509,7 +2509,7 @@ static bool ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915) { - return (((IS_ELKHARTLAKE(i915) || IS_JASPERLAKE(i915)) && + return ((IS_ELKHARTLAKE(i915) && IS_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) && i915->display.dpll.ref_clks.nssc == 38400; @@ -3308,6 +3308,8 @@ struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); struct icl_port_dpll *port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT]; struct skl_wrpll_params pll_params = {}; @@ -3326,7 +3328,11 @@ return ret; /* this is mainly for the fastset check */ - icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY); + if (old_crtc_state->shared_dpll && + old_crtc_state->shared_dpll->info->id == DPLL_ID_ICL_TBTPLL) + icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT); + else + icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY); crtc_state->port_clock = icl_ddi_mg_pll_get_freq(i915, NULL, &port_dpll->hw_state); @@ -4023,7 +4029,8 @@ static const struct dpll_info icl_plls[] = { { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, }, { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, }, - { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, }, + { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, + .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, }, { .name = "MG PLL 1", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, }, { .name = "MG PLL 2", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, }, { .name = "MG PLL 3", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, }, @@ -4068,7 +4075,8 @@ static const struct dpll_info tgl_plls[] = { { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, }, { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, }, - { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, }, + { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, + .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, }, { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, }, { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, }, { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, }, @@ -4141,7 +4149,8 @@ static const struct dpll_info adlp_plls[] = { { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, }, { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, }, - { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, }, + { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, + .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, }, { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, }, { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, }, { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, }, @@ -4465,31 +4474,29 @@ struct intel_crtc *crtc, const struct intel_crtc_state *new_crtc_state) { - struct intel_dpll_hw_state dpll_hw_state; + struct intel_dpll_hw_state dpll_hw_state = {}; u8 pipe_mask; bool active; - memset(&dpll_hw_state, 0, sizeof(dpll_hw_state)); - - drm_dbg_kms(&i915->drm, "%s\n", pll->info->name); - active = intel_dpll_get_hw_state(i915, pll, &dpll_hw_state); if (!(pll->info->flags & INTEL_DPLL_ALWAYS_ON)) { I915_STATE_WARN(i915, !pll->on && pll->active_mask, - "pll in active use but not on in sw tracking\n"); + "%s: pll in active use but not on in sw tracking\n", + pll->info->name); I915_STATE_WARN(i915, pll->on && !pll->active_mask, - "pll is on but not used by any active pipe\n"); + "%s: pll is on but not used by any active pipe\n", + pll->info->name); I915_STATE_WARN(i915, pll->on != active, - "pll on state mismatch (expected %i, found %i)\n", - pll->on, active); + "%s: pll on state mismatch (expected %i, found %i)\n", + pll->info->name, pll->on, active); } if (!crtc) { I915_STATE_WARN(i915, pll->active_mask & ~pll->state.pipe_mask, - "more active pll users than references: 0x%x vs 0x%x\n", - pll->active_mask, pll->state.pipe_mask); + "%s: more active pll users than references: 0x%x vs 0x%x\n", + pll->info->name, pll->active_mask, pll->state.pipe_mask); return; } @@ -4498,21 +4505,30 @@ if (new_crtc_state->hw.active) I915_STATE_WARN(i915, !(pll->active_mask & pipe_mask), - "pll active mismatch (expected pipe %c in active mask 0x%x)\n", - pipe_name(crtc->pipe), pll->active_mask); + "%s: pll active mismatch (expected pipe %c in active mask 0x%x)\n", + pll->info->name, pipe_name(crtc->pipe), pll->active_mask); else I915_STATE_WARN(i915, pll->active_mask & pipe_mask, - "pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n", - pipe_name(crtc->pipe), pll->active_mask); + "%s: pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n", + pll->info->name, pipe_name(crtc->pipe), pll->active_mask); I915_STATE_WARN(i915, !(pll->state.pipe_mask & pipe_mask), - "pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n", - pipe_mask, pll->state.pipe_mask); + "%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n", + pll->info->name, pipe_mask, pll->state.pipe_mask); I915_STATE_WARN(i915, pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state, sizeof(dpll_hw_state)), - "pll hw state mismatch\n"); + "%s: pll hw state mismatch\n", + pll->info->name); +} + +static bool has_alt_port_dpll(const struct intel_shared_dpll *old_pll, + const struct intel_shared_dpll *new_pll) +{ + return old_pll && new_pll && old_pll != new_pll && + (old_pll->info->flags & INTEL_DPLL_IS_ALT_PORT_DPLL || + new_pll->info->flags & INTEL_DPLL_IS_ALT_PORT_DPLL); } void intel_shared_dpll_state_verify(struct intel_atomic_state *state, @@ -4534,11 +4550,15 @@ struct intel_shared_dpll *pll = old_crtc_state->shared_dpll; I915_STATE_WARN(i915, pll->active_mask & pipe_mask, - "pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n", - pipe_name(crtc->pipe), pll->active_mask); - I915_STATE_WARN(i915, pll->state.pipe_mask & pipe_mask, - "pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n", - pipe_name(crtc->pipe), pll->state.pipe_mask); + "%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n", + pll->info->name, pipe_name(crtc->pipe), pll->active_mask); + + /* TC ports have both MG/TC and TBT PLL referenced simultaneously */ + I915_STATE_WARN(i915, !has_alt_port_dpll(old_crtc_state->shared_dpll, + new_crtc_state->shared_dpll) && + pll->state.pipe_mask & pipe_mask, + "%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n", + pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask); } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -277,12 +277,16 @@ enum intel_display_power_domain power_domain; #define INTEL_DPLL_ALWAYS_ON (1 << 0) +#define INTEL_DPLL_IS_ALT_PORT_DPLL (1 << 1) /** * @flags: * * INTEL_DPLL_ALWAYS_ON * Inform the state checker that the DPLL is kept enabled even if * not in use by any CRTC. + * INTEL_DPLL_IS_ALT_PORT_DPLL + * Inform the state checker that the DPLL can be used as a fallback + * (for TC->TBT fallback). */ u32 flags; }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dsb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_dsb.c @@ -340,6 +340,17 @@ return max(0, vblank_start - intel_usecs_to_scanlines(adjusted_mode, latency)); } +static u32 dsb_chicken(struct intel_crtc *crtc) +{ + if (crtc->mode_flags & I915_MODE_FLAG_VRR) + return DSB_CTRL_WAIT_SAFE_WINDOW | + DSB_CTRL_NO_WAIT_VBLANK | + DSB_INST_WAIT_SAFE_WINDOW | + DSB_INST_NO_WAIT_VBLANK; + else + return 0; +} + static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl, int dewake_scanline) { @@ -361,6 +372,9 @@ intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id), ctrl | DSB_ENABLE); + intel_de_write_fw(dev_priv, DSB_CHICKEN(pipe, dsb->id), + dsb_chicken(crtc)); + intel_de_write_fw(dev_priv, DSB_HEAD(pipe, dsb->id), intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf)); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -255,6 +255,16 @@ return PTR_ERR(vma); plane_state->ggtt_vma = vma; + + /* + * Pre-populate the dma address before we enter the vblank + * evade critical section as i915_gem_object_get_dma_address() + * will trigger might_sleep() even if it won't actually sleep, + * which is the case when the fb has already been pinned. + */ + if (phys_cursor) + plane_state->phys_dma_addr = + i915_gem_object_get_dma_address(intel_fb_obj(fb), 0); } else { struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -177,6 +177,14 @@ handle_simple_irq, "hdmi_lpe_audio_irq_handler"); + static const struct pci_device_id irq_quirk_ids[] = { + /* Dell Wyse 3040 */ + {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x22b0, 0x1028, 0x07c1)}, + {} + }; + + if (pci_dev_present(irq_quirk_ids)) + return 0; return irq_set_chip_data(irq, dev_priv); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_psr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_psr.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "i915_drv.h" #include "i915_reg.h" @@ -762,8 +763,8 @@ static int psr2_block_count_lines(struct intel_dp *intel_dp) { - return intel_dp->psr.io_wake_lines < 9 && - intel_dp->psr.fast_wake_lines < 9 ? 8 : 12; + return intel_dp->psr.alpm_parameters.io_wake_lines < 9 && + intel_dp->psr.alpm_parameters.fast_wake_lines < 9 ? 8 : 12; } static int psr2_block_count(struct intel_dp *intel_dp) @@ -800,6 +801,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_psr *psr = &intel_dp->psr; enum transcoder cpu_transcoder = intel_dp->psr.transcoder; u32 val = EDP_PSR2_ENABLE; u32 psr_val = 0; @@ -841,17 +843,18 @@ */ int tmp; - tmp = map[intel_dp->psr.io_wake_lines - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES]; + tmp = map[psr->alpm_parameters.io_wake_lines - + TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES]; val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(tmp + TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES); - tmp = map[intel_dp->psr.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES]; + tmp = map[psr->alpm_parameters.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES]; val |= TGL_EDP_PSR2_FAST_WAKE(tmp + TGL_EDP_PSR2_FAST_WAKE_MIN_LINES); } else if (DISPLAY_VER(dev_priv) >= 12) { - val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_wake_lines); - val |= TGL_EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake_lines); + val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines); + val |= TGL_EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines); } else if (DISPLAY_VER(dev_priv) >= 9) { - val |= EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_wake_lines); - val |= EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake_lines); + val |= EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines); + val |= EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines); } if (intel_dp->psr.req_psr2_sdp_prior_scanline) @@ -1013,11 +1016,57 @@ crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines; } +struct edid_mfgid_prodcode { + u8 mfg_id0; + u8 mfg_id1; + u8 prod_code0; + u8 prod_code1; +}; + +#define PSR2_DISABLE_QUIRK_ENTRY(id0, id1, code0, code1) \ + { .mfg_id0 = (id0), .mfg_id1 = (id1), .prod_code0 = (code0), .prod_code1 = (code1) } + +static struct edid_mfgid_prodcode psr2_disable_quirk_tbl[] = { + PSR2_DISABLE_QUIRK_ENTRY(0x4d, 0x10, 0x8f, 0x15), /* A sharp QHD panel */ + PSR2_DISABLE_QUIRK_ENTRY(0x4d, 0x10, 0x93, 0x15), /* A sharp FHD panel */ + PSR2_DISABLE_QUIRK_ENTRY(0x30, 0xe4, 0x8b, 0x07), /* A LG FHD panel */ + PSR2_DISABLE_QUIRK_ENTRY(0x30, 0xe4, 0x78, 0x07), /* A LG OLED panel */ + PSR2_DISABLE_QUIRK_ENTRY(0x30, 0xe4, 0x8c, 0x07), /* A LG QHD panel */ + PSR2_DISABLE_QUIRK_ENTRY(0x06, 0xaf, 0x9a, 0xf9), /* An AUO panel */ + PSR2_DISABLE_QUIRK_ENTRY(0x06, 0xaf, 0xa3, 0xc3), /* An AUO panel */ + { } +}; + +static bool is_edid_in_psr2_disable_quirk_tbl(struct intel_dp *intel_dp) +{ + const struct edid *p_edid; + int i; + + p_edid = intel_dp_fetch_edid(intel_dp); + if (p_edid) { + for (i = 0; i < ARRAY_SIZE(psr2_disable_quirk_tbl); i ++) { + if (p_edid->mfg_id[0] == psr2_disable_quirk_tbl[i].mfg_id0 && + p_edid->mfg_id[1] == psr2_disable_quirk_tbl[i].mfg_id1 && + p_edid->prod_code[0] == psr2_disable_quirk_tbl[i].prod_code0 && + p_edid->prod_code[1] == psr2_disable_quirk_tbl[i].prod_code1) + return true; + } + } + + return false; +} + static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + if (is_edid_in_psr2_disable_quirk_tbl(intel_dp)) { + drm_info_once(&dev_priv->drm, + "PSR2 sel fetch disabled by the edid quirk table\n"); + return false; + } + if (!dev_priv->display.params.enable_psr2_sel_fetch && intel_dp->psr.debug != I915_PSR_DEBUG_ENABLE_SEL_FETCH) { drm_dbg_kms(&dev_priv->drm, @@ -1101,26 +1150,76 @@ return true; } -static bool _compute_psr2_wake_times(struct intel_dp *intel_dp, +static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); + int check_entry_lines; + + if (DISPLAY_VER(i915) < 20) + return true; + + /* ALPM Entry Check = 2 + CEILING( 5us /tline ) */ + check_entry_lines = 2 + + intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5); + + if (check_entry_lines > 15) + return false; + + if (i915->display.params.psr_safest_params) + check_entry_lines = 15; + + intel_dp->psr.alpm_parameters.check_entry_lines = check_entry_lines; + + return true; +} + +/* + * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There + * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are + * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us. + */ +static int skl_io_buffer_wake_time(void) +{ + return 18; +} + +static int tgl_io_buffer_wake_time(void) +{ + return 10; +} + +static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + + if (DISPLAY_VER(i915) >= 12) + return tgl_io_buffer_wake_time(); + else + return skl_io_buffer_wake_time(); +} + +static bool _compute_alpm_params(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time; + int tfw_exit_latency = 20; /* eDP spec */ + int phy_wake = 4; /* eDP spec */ + int preamble = 8; /* eDP spec */ + int precharge = intel_dp_aux_fw_sync_len() - preamble; u8 max_wake_lines; - if (DISPLAY_VER(i915) >= 12) { - io_wake_time = 42; - /* - * According to Bspec it's 42us, but based on testing - * it is not enough -> use 45 us. - */ - fast_wake_time = 45; + io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) + + preamble + phy_wake + tfw_exit_latency; + fast_wake_time = precharge + preamble + phy_wake + + tfw_exit_latency; + + if (DISPLAY_VER(i915) >= 12) + /* TODO: Check how we can use ALPM_CTL fast wake extended field */ max_wake_lines = 12; - } else { - io_wake_time = 50; - fast_wake_time = 32; + else max_wake_lines = 8; - } io_wake_lines = intel_usecs_to_scanlines( &crtc_state->hw.adjusted_mode, io_wake_time); @@ -1131,12 +1230,15 @@ fast_wake_lines > max_wake_lines) return false; + if (!_lnl_compute_alpm_params(intel_dp, crtc_state)) + return false; + if (i915->display.params.psr_safest_params) io_wake_lines = fast_wake_lines = max_wake_lines; /* According to Bspec lower limit should be set as 7 lines. */ - intel_dp->psr.io_wake_lines = max(io_wake_lines, 7); - intel_dp->psr.fast_wake_lines = max(fast_wake_lines, 7); + intel_dp->psr.alpm_parameters.io_wake_lines = max(io_wake_lines, 7); + intel_dp->psr.alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7); return true; } @@ -1268,7 +1370,7 @@ return false; } - if (!_compute_psr2_wake_times(intel_dp, crtc_state)) { + if (!_compute_alpm_params(intel_dp, crtc_state)) { drm_dbg_kms(&dev_priv->drm, "PSR2 not enabled, Unable to use long enough wake times\n"); return false; @@ -1368,6 +1470,17 @@ return; } + /* + * FIXME figure out what is wrong with PSR+bigjoiner and + * fix it. Presumably something related to the fact that + * PSR is a transcoder level feature. + */ + if (crtc_state->bigjoiner_pipes) { + drm_dbg_kms(&dev_priv->drm, + "PSR disabled due to bigjoiner\n"); + return; + } + if (CAN_PANEL_REPLAY(intel_dp)) crtc_state->has_panel_replay = true; else @@ -1504,6 +1617,21 @@ wa_16013835468_bit_get(intel_dp), 0); } +static void lnl_alpm_configure(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + enum transcoder cpu_transcoder = intel_dp->psr.transcoder; + struct intel_psr *psr = &intel_dp->psr; + + if (DISPLAY_VER(dev_priv) < 20) + return; + + intel_de_write(dev_priv, ALPM_CTL(cpu_transcoder), + ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE | + ALPM_CTL_ALPM_ENTRY_CHECK(psr->alpm_parameters.check_entry_lines) | + ALPM_CTL_EXTENDED_FAST_WAKE_TIME(psr->alpm_parameters.fast_wake_lines)); +} + static void intel_psr_enable_source(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -1569,6 +1697,8 @@ intel_dp->psr.psr2_sel_fetch_enabled ? IGNORE_PSR2_HW_TRACKING : 0); + lnl_alpm_configure(intel_dp); + /* * Wa_16013835468 * Wa_14015648006 --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_psr_regs.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_psr_regs.h @@ -290,4 +290,61 @@ _SEL_FETCH_PLANE_OFFSET_1_A - \ _SEL_FETCH_PLANE_BASE_1_A) +#define _ALPM_CTL_A 0x60950 +#define ALPM_CTL(tran) _MMIO_TRANS2(tran, _ALPM_CTL_A) +#define ALPM_CTL_ALPM_ENABLE REG_BIT(31) +#define ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(30) +#define ALPM_CTL_LOBF_ENABLE REG_BIT(29) +#define ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE REG_BIT(28) +#define ALPM_CTL_KEEP_FEC_ENABLE_FOR_AUX_WAKE_SLEEP REG_BIT(27) +#define ALPM_CTL_RESTORE_OCCURED REG_BIT(26) +#define ALPM_CTL_RESTORE_TO_SLEEP REG_BIT(25) +#define ALPM_CTL_RESTORE_TO_DEEP_SLEEP REG_BIT(24) +#define ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK REG_GENMASK(23, 21) +#define ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 0) +#define ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_128_SYMBOLS REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 1) +#define ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_256_SYMBOLS REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 2) +#define ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_512_SYMBOLS REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 3) +#define ALPM_CTL_AUX_WAKE_SLEEP_HOLD_ENABLE REG_BIT(20) +#define ALPM_CTL_ALPM_ENTRY_CHECK_MASK REG_GENMASK(19, 16) +#define ALPM_CTL_ALPM_ENTRY_CHECK(val) REG_FIELD_PREP(ALPM_CTL_ALPM_ENTRY_CHECK_MASK, val) +#define ALPM_CTL_EXTENDED_FAST_WAKE_TIME_MASK REG_GENMASK(13, 8) +#define ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES 5 +#define ALPM_CTL_EXTENDED_FAST_WAKE_TIME(lines) REG_FIELD_PREP(ALPM_CTL_EXTENDED_FAST_WAKE_TIME_MASK, (lines) - ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES) +#define ALPM_CTL_AUX_LESS_WAKE_TIME_MASK REG_GENMASK(5, 0) +#define ALPM_CTL_AUX_LESS_WAKE_TIME(val) REG_FIELD_PREP(ALPM_CTL_AUX_LESS_WAKE_TIME_MASK, val) + +#define _ALPM_CTL2_A 0x60954 +#define ALPM_CTL2(tran) _MMIO_TRANS2(tran, _ALPM_CTL2_A) +#define ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK REG_GENMASK(28, 24) +#define ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY(val) REG_FIELD_PREP(ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK, val) +#define ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION_MASK REG_GENMASK(19, 16) +#define ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION(val) REG_FIELD_PREP(ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION_MASK, val) +#define ALPM_CTL2_NUMBER_OF_LTTPR_MASK REG_GENMASK(15, 12) +#define ALPM_CTL2_NUMBER_OF_LTTPR(val) REG_FIELD_PREP(ALPM_CTL2_NUMBER_OF_LTTPR_MASK, val) +#define ALPM_CTL2_LTTPR_AUX_LESS_SLEEP_HOLD_TIME_MASK REG_GENMASK(10, 8) +#define ALPM_CTL2_LTTPR_AUX_LESS_SLEEP_HOLD_TIME(val) REG_FIELD_PREP(ALPM_CTL2_LTTPR_AUX_LESS_SLEEP_HOLD_TIME_MASK, val) +#define ALPM_CTL2_FEC_DECODE_EN_POSITION_AFTER_WAKE_SR REG_BIT(4) +#define ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES_MASK REG_GENMASK(2, 0) +#define ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES(val) REG_FIELD_PREP(ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES_MASK, val) + +#define _PORT_ALPM_CTL_A 0x16fa2c +#define PORT_ALPM_CTL(tran) _MMIO_TRANS2(tran, _PORT_ALPM_CTL_A) +#define PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE REG_BIT(31) +#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK REG_GENMASK(23, 20) +#define PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK, val) +#define PORT_ALPM_CTL_MAX_PHY_SWING_HOLD_MASK REG_GENMASK(19, 16) +#define PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(val) REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_HOLD_MASK, val) +#define PORT_ALPM_CTL_SILENCE_PERIOD_MASK REG_GENMASK(7, 0) +#define PORT_ALPM_CTL_SILENCE_PERIOD(val) REG_FIELD_PREP(PORT_ALPM_CTL_SILENCE_PERIOD_MASK, val) + +#define _PORT_ALPM_LFPS_CTL_A 0x16fa30 +#define PORT_ALPM_LFPS_CTL(tran) _MMIO_TRANS2(tran, _PORT_ALPM_LFPS_CTL_A) +#define PORT_ALPM_LFPS_CTL_LFPS_START_POLARITY REG_BIT(31) +#define PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MASK REG_GENMASK(27, 24) +#define ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES 5 +#define ALPM_CTL_EXTENDED_FAST_WAKE_TIME(lines) REG_FIELD_PREP(ALPM_CTL_EXTENDED_FAST_WAKE_TIME_MASK, (lines) - ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES) +#define ALPM_CTL_AUX_LESS_WAKE_TIME_MASK REG_GENMASK(5, 0) +#define ALPM_CTL_AUX_LESS_WAKE_TIME(val) REG_FIELD_PREP(ALPM_CTL_AUX_LESS_WAKE_TIME_MASK, val) + #endif /* __INTEL_PSR_REGS_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_sdvo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -1830,8 +1830,6 @@ struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); u32 temp; - encoder->audio_disable(encoder, old_crtc_state, conn_state); - intel_sdvo_set_active_outputs(intel_sdvo, 0); if (0) intel_sdvo_set_encoder_power_state(intel_sdvo, @@ -1923,8 +1921,6 @@ intel_sdvo_set_encoder_power_state(intel_sdvo, DRM_MODE_DPMS_ON); intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo_connector->output_flag); - - encoder->audio_enable(encoder, pipe_config, conn_state); } static enum drm_mode_status --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_vbt_defs.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_vbt_defs.h @@ -897,11 +897,6 @@ u16 reserved; } __packed; -#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \ - offsetof(struct bdb_lfp_backlight_data, brightness_level) -#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \ - offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits) - struct bdb_lfp_backlight_data { u8 entry_size; struct lfp_backlight_data_entry data[16]; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/intel_vrr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/intel_vrr.c @@ -117,6 +117,13 @@ const struct drm_display_info *info = &connector->base.display_info; int vmin, vmax; + /* + * FIXME all joined pipes share the same transcoder. + * Need to account for that during VRR toggle/push/etc. + */ + if (crtc_state->bigjoiner_pipes) + return; + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) return; @@ -187,10 +194,11 @@ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; /* - * TRANS_SET_CONTEXT_LATENCY with VRR enabled - * requires this chicken bit on ADL/DG2. + * This bit seems to have two meanings depending on the platform: + * TGL: generate VRR "safe window" for DSB vblank waits + * ADL/DG2: make TRANS_SET_CONTEXT_LATENCY effective with VRR */ - if (DISPLAY_VER(dev_priv) == 13) + if (IS_DISPLAY_VER(dev_priv, 12, 13)) intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0, PIPE_VBLANK_WITH_DELAY); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2290,6 +2290,9 @@ if (HAS_4TILE(i915)) caps |= INTEL_PLANE_CAP_TILING_4; + if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(i915)) + return caps; + if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) { caps |= INTEL_PLANE_CAP_CCS_RC; if (DISPLAY_VER(i915) >= 12) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/skl_watermark.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/skl_watermark.c @@ -63,7 +63,7 @@ return DISPLAY_VER(i915) == 9; } -static bool +bool intel_has_sagv(struct drm_i915_private *i915) { return HAS_SAGV(i915) && --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/display/skl_watermark.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/display/skl_watermark.h @@ -25,6 +25,7 @@ void intel_sagv_post_plane_update(struct intel_atomic_state *state); bool intel_can_enable_sagv(struct drm_i915_private *i915, const struct intel_bw_state *bw_state); +bool intel_has_sagv(struct drm_i915_private *i915); u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915, const struct skl_ddb_entry *entry); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -284,7 +284,9 @@ static inline bool i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj) { - return i915_gem_object_type_has(obj, I915_GEM_OBJECT_IS_SHRINKABLE); + /* TODO: make DPT shrinkable when it has no bound vmas */ + return i915_gem_object_type_has(obj, I915_GEM_OBJECT_IS_SHRINKABLE) && + !obj->is_dpt; } static inline bool --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -944,7 +944,11 @@ dsm_size = ALIGN_DOWN(lmem_size - dsm_base, SZ_1M); } - if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) { + if (i915_direct_stolen_access(i915)) { + drm_dbg(&i915->drm, "Using direct DSM access\n"); + io_start = intel_uncore_read64(uncore, GEN12_DSMBASE) & GEN12_BDSM_MASK; + io_size = dsm_size; + } else if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) { io_start = 0; io_size = 0; } else { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/gen8_engine_cs.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/gen8_engine_cs.c @@ -226,7 +226,7 @@ static int mtl_dummy_pipe_control(struct i915_request *rq) { /* Wa_14016712196 */ - if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 71)) || + if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(rq->i915)) { u32 *cs; @@ -743,21 +743,25 @@ } /* Wa_14014475959:dg2 */ -#define CCS_SEMAPHORE_PPHWSP_OFFSET 0x540 -static u32 ccs_semaphore_offset(struct i915_request *rq) +/* Wa_16019325821 */ +/* Wa_14019159160 */ +#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540 +static u32 hold_switchout_semaphore_offset(struct i915_request *rq) { return i915_ggtt_offset(rq->context->state) + - (LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET; + (LRC_PPHWSP_PN * PAGE_SIZE) + HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET; } /* Wa_14014475959:dg2 */ -static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs) +/* Wa_16019325821 */ +/* Wa_14019159160 */ +static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs) { int i; *cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL | MI_ATOMIC_MOVE; - *cs++ = ccs_semaphore_offset(rq); + *cs++ = hold_switchout_semaphore_offset(rq); *cs++ = 0; *cs++ = 1; @@ -773,7 +777,7 @@ MI_SEMAPHORE_POLL | MI_SEMAPHORE_SAD_EQ_SDD; *cs++ = 0; - *cs++ = ccs_semaphore_offset(rq); + *cs++ = hold_switchout_semaphore_offset(rq); *cs++ = 0; return cs; @@ -790,8 +794,10 @@ cs = gen12_emit_preempt_busywait(rq, cs); /* Wa_14014475959:dg2 */ - if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine)) - cs = ccs_emit_wa_busywait(rq, cs); + /* Wa_16019325821 */ + /* Wa_14019159160 */ + if (intel_engine_uses_wa_hold_switchout(rq->engine)) + cs = hold_switchout_emit_wa_busywait(rq, cs); rq->tail = intel_ring_offset(rq, cs); assert_ring_tail_valid(rq->ring, rq->tail); @@ -822,7 +828,7 @@ flags |= PIPE_CONTROL_FLUSH_L3; /* Wa_14016712196 */ - if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915)) + if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915)) /* dummy PIPE_CONTROL + depth flush */ cs = gen12_emit_pipe_control(cs, 0, PIPE_CONTROL_DEPTH_CACHE_FLUSH, 0); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/gen8_ppgtt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/gen8_ppgtt.c @@ -961,6 +961,9 @@ struct i915_vma *vma; int ret; + if (!intel_gt_needs_wa_16018031267(vm->gt)) + return 0; + /* The memory will be used only by GPU. */ obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, I915_BO_ALLOC_VOLATILE | --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -263,8 +263,13 @@ i915_request_put(rq); } + /* Lazy irq enabling after HW submission */ if (!READ_ONCE(b->irq_armed) && !list_empty(&b->signalers)) intel_breadcrumbs_arm_irq(b); + + /* And confirm that we still want irqs enabled before we yield */ + if (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) + intel_breadcrumbs_disarm_irq(b); } struct intel_breadcrumbs * @@ -315,13 +320,7 @@ return; /* Kick the work once more to drain the signalers, and disarm the irq */ - irq_work_sync(&b->irq_work); - while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) { - local_irq_disable(); - signal_irq_work(&b->irq_work); - local_irq_enable(); - cond_resched(); - } + irq_work_queue(&b->irq_work); } void intel_breadcrumbs_free(struct kref *kref) @@ -404,7 +403,7 @@ * the request as it may have completed and raised the interrupt as * we were attaching it into the lists. */ - if (!b->irq_armed || __i915_request_is_complete(rq)) + if (!READ_ONCE(b->irq_armed) || __i915_request_is_complete(rq)) irq_work_queue(&b->irq_work); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -908,6 +908,29 @@ info->engine_mask &= ~BIT(GSC0); } + /* + * Do not create the command streamer for CCS slices beyond the first. + * All the workload submitted to the first engine will be shared among + * all the slices. + * + * Once the user will be allowed to customize the CCS mode, then this + * check needs to be removed. + */ + if (IS_DG2(gt->i915)) { + u8 first_ccs = __ffs(CCS_MASK(gt)); + + /* + * Store the number of active cslices before + * changing the CCS engine configuration + */ + gt->ccs.cslices = CCS_MASK(gt); + + /* Mask off all the CCS engine */ + info->engine_mask &= ~GENMASK(CCS3, CCS0); + /* Put back in the first CCS engine */ + info->engine_mask |= BIT(_CCS(first_ccs)); + } + return info->engine_mask; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_engine_pm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_engine_pm.c @@ -279,9 +279,6 @@ intel_engine_park_heartbeat(engine); intel_breadcrumbs_park(engine->breadcrumbs); - /* Must be reset upon idling, or we may miss the busy wakeup. */ - GEM_BUG_ON(engine->sched_engine->queue_priority_hint != INT_MIN); - if (engine->park) engine->park(engine); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -586,7 +586,7 @@ #define I915_ENGINE_HAS_RCS_REG_STATE BIT(9) #define I915_ENGINE_HAS_EU_PRIORITY BIT(10) #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11) -#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12) +#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12) unsigned int flags; /* @@ -696,10 +696,12 @@ } /* Wa_14014475959:dg2 */ +/* Wa_16019325821 */ +/* Wa_14019159160 */ static inline bool -intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine) +intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine) { - return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT; + return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT; } #endif /* __INTEL_ENGINE_TYPES_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -3272,6 +3272,9 @@ { cancel_timer(&engine->execlists.timer); cancel_timer(&engine->execlists.preempt); + + /* Reset upon idling, or we may delay the busy wakeup. */ + WRITE_ONCE(engine->sched_engine->queue_priority_hint, INT_MIN); } static void add_to_engine(struct i915_request *rq) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -24,6 +24,7 @@ #include "intel_ring.h" #include "i915_drv.h" #include "i915_pci.h" +#include "i915_reg.h" #include "i915_request.h" #include "i915_scatterlist.h" #include "i915_utils.h" @@ -1152,13 +1153,20 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size) { struct drm_i915_private *i915 = ggtt->vm.i915; + struct intel_uncore *uncore = ggtt->vm.gt->uncore; struct pci_dev *pdev = to_pci_dev(i915->drm.dev); phys_addr_t phys_addr; u32 pte_flags; int ret; GEM_WARN_ON(pci_resource_len(pdev, GEN4_GTTMMADR_BAR) != gen6_gttmmadr_size(i915)); - phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915); + + if (i915_direct_stolen_access(i915)) { + drm_dbg(&i915->drm, "Using direct GSM access\n"); + phys_addr = intel_uncore_read64(uncore, GEN12_GSMBASE) & GEN12_BDSM_MASK; + } else { + phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915); + } if (needs_wc_ggtt_mapping(i915)) ggtt->gsm = ioremap_wc(phys_addr, size); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c @@ -298,6 +298,7 @@ return; GEM_BUG_ON(fence->vma != vma); + i915_active_wait(&fence->active); GEM_BUG_ON(!i915_active_is_idle(&fence->active)); GEM_BUG_ON(atomic_read(&fence->pin_count)); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_gt.c @@ -1024,6 +1024,12 @@ return I915_MAP_WC; } +bool intel_gt_needs_wa_16018031267(struct intel_gt *gt) +{ + /* Wa_16018031267, Wa_16018063123 */ + return IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 55), IP_VER(12, 71)); +} + bool intel_gt_needs_wa_22016122933(struct intel_gt *gt) { return MEDIA_VER_FULL(gt->i915) == IP_VER(13, 0) && gt->type == GT_MEDIA; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_gt.h @@ -82,17 +82,18 @@ ##__VA_ARGS__); \ } while (0) -#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \ - IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 55), IP_VER(12, 71)) && \ - engine->class == COPY_ENGINE_CLASS && engine->instance == 0) - static inline bool gt_is_root(struct intel_gt *gt) { return !gt->info.id; } +bool intel_gt_needs_wa_16018031267(struct intel_gt *gt); bool intel_gt_needs_wa_22016122933(struct intel_gt *gt); +#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \ + intel_gt_needs_wa_16018031267(engine->gt) && \ + engine->class == COPY_ENGINE_CLASS && engine->instance == 0) + static inline struct intel_gt *uc_to_gt(struct intel_uc *uc) { return container_of(uc, struct intel_gt, uc); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2024 Intel Corporation + */ + +#include "i915_drv.h" +#include "intel_gt.h" +#include "intel_gt_ccs_mode.h" +#include "intel_gt_regs.h" + +unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt) +{ + int cslice; + u32 mode = 0; + int first_ccs = __ffs(CCS_MASK(gt)); + + if (!IS_DG2(gt->i915)) + return 0; + + /* Build the value for the fixed CCS load balancing */ + for (cslice = 0; cslice < I915_MAX_CCS; cslice++) { + if (gt->ccs.cslices & BIT(cslice)) + /* + * If available, assign the cslice + * to the first available engine... + */ + mode |= XEHP_CCS_MODE_CSLICE(cslice, first_ccs); + + else + /* + * ... otherwise, mark the cslice as + * unavailable if no CCS dispatches here + */ + mode |= XEHP_CCS_MODE_CSLICE(cslice, + XEHP_CCS_MODE_CSLICE_MASK); + } + + return mode; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef __INTEL_GT_CCS_MODE_H__ +#define __INTEL_GT_CCS_MODE_H__ + +struct intel_gt; + +unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt); + +#endif /* __INTEL_GT_CCS_MODE_H__ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -1477,8 +1477,14 @@ #define ECOBITS_PPGTT_CACHE4B (0 << 8) #define GEN12_RCU_MODE _MMIO(0x14800) +#define XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE REG_BIT(1) #define GEN12_RCU_MODE_CCS_ENABLE REG_BIT(0) +#define XEHP_CCS_MODE _MMIO(0x14804) +#define XEHP_CCS_MODE_CSLICE_MASK REG_GENMASK(2, 0) /* CCS0-3 + rsvd */ +#define XEHP_CCS_MODE_CSLICE_WIDTH ilog2(XEHP_CCS_MODE_CSLICE_MASK + 1) +#define XEHP_CCS_MODE_CSLICE(cslice, ccs) (ccs << (cslice * XEHP_CCS_MODE_CSLICE_WIDTH)) + #define CHV_FUSE_GT _MMIO(VLV_GUNIT_BASE + 0x2168) #define CHV_FGT_DISABLE_SS0 (1 << 10) #define CHV_FGT_DISABLE_SS1 (1 << 11) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -207,6 +207,14 @@ [MAX_ENGINE_INSTANCE + 1]; enum intel_submission_method submission_method; + struct { + /* + * Mask of the non fused CCS slices + * to be used for the load balancing + */ + intel_engine_mask_t cslices; + } ccs; + /* * Default address space (either GGTT or ppGTT depending on arch). * --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -10,6 +10,7 @@ #include "intel_engine_regs.h" #include "intel_gpu_commands.h" #include "intel_gt.h" +#include "intel_gt_ccs_mode.h" #include "intel_gt_mcr.h" #include "intel_gt_print.h" #include "intel_gt_regs.h" @@ -51,7 +52,8 @@ * registers belonging to BCS, VCS or VECS should be implemented in * xcs_engine_wa_init(). Workarounds for registers not belonging to a specific * engine's MMIO range but that are part of of the common RCS/CCS reset domain - * should be implemented in general_render_compute_wa_init(). + * should be implemented in general_render_compute_wa_init(). The settings + * about the CCS load balancing should be added in ccs_engine_wa_mode(). * * - GT workarounds: the list of these WAs is applied whenever these registers * revert to their default values: on GPU reset, suspend/resume [1]_, etc. @@ -789,8 +791,13 @@ dg2_ctx_gt_tuning_init(engine, wal); - if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) || - IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER)) + /* + * Due to Wa_16014892111, the DRAW_WATERMARK tuning must be done in + * gen12_emit_indirect_ctx_rcs() rather than here on some early + * steppings. + */ + if (!(IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) || + IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0))) wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false); } @@ -908,7 +915,7 @@ if (engine->class != RENDER_CLASS) goto done; - if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71))) + if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74))) xelpg_ctx_workarounds_init(engine, wal); else if (IS_PONTEVECCHIO(i915)) ; /* noop; none at this time */ @@ -1643,7 +1650,8 @@ static void xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) { - /* Wa_14018778641 / Wa_18018781329 */ + /* Wa_14018575942 / Wa_18018781329 */ + wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB); wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB); /* Wa_22016670082 */ @@ -1710,7 +1718,7 @@ */ static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal) { - if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) { + if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) { wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS); wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS); } @@ -1743,7 +1751,7 @@ return; } - if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) + if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) xelpg_gt_workarounds_init(gt, wal); else if (IS_PONTEVECCHIO(i915)) pvc_gt_workarounds_init(gt, wal); @@ -2216,7 +2224,7 @@ if (engine->gt->type == GT_MEDIA) ; /* none yet */ - else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71))) + else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74))) xelpg_whitelist_build(engine); else if (IS_PONTEVECCHIO(i915)) pvc_whitelist_build(engine); @@ -2828,7 +2836,7 @@ { struct drm_i915_private *i915 = gt->i915; - if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915)) + if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915)) wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512); /* @@ -2844,6 +2852,30 @@ wa_write_clr(wal, GEN8_GARBCNTL, GEN12_BUS_HASH_CTL_BIT_EXC); } +static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal) +{ + struct intel_gt *gt = engine->gt; + u32 mode; + + if (!IS_DG2(gt->i915)) + return; + + /* + * Wa_14019159160: This workaround, along with others, leads to + * significant challenges in utilizing load balancing among the + * CCS slices. Consequently, an architectural decision has been + * made to completely disable automatic CCS load balancing. + */ + wa_masked_en(wal, GEN12_RCU_MODE, XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE); + + /* + * After having disabled automatic load balancing we need to + * assign all slices to a single CCS. We will call it CCS mode 1 + */ + mode = intel_gt_apply_ccs_mode(gt); + wa_masked_en(wal, XEHP_CCS_MODE, mode); +} + /* * The workarounds in this function apply to shared registers in * the general render reset domain that aren't tied to a @@ -2881,7 +2913,8 @@ } if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) || - IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER)) + IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER) || + IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 74), IP_VER(12, 74))) /* Wa_14017856879 */ wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH); @@ -2993,8 +3026,10 @@ * to a single RCS/CCS engine's workaround list since * they're reset as part of the general render domain reset. */ - if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) + if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) { general_render_compute_wa_init(engine, wal); + ccs_engine_wa_mode(engine, wal); + } if (engine->class == COMPUTE_CLASS) ccs_engine_wa_init(engine, wal); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h @@ -36,6 +36,7 @@ INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_START, INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID = 0x73, INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID = 0x74, + INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR = 0x75, INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END, INTEL_GUC_LOAD_STATUS_READY = 0xF0, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h @@ -29,9 +29,9 @@ */ #define GUC_KLV_LEN_MIN 1u -#define GUC_KLV_0_KEY (0xffff << 16) -#define GUC_KLV_0_LEN (0xffff << 0) -#define GUC_KLV_n_VALUE (0xffffffff << 0) +#define GUC_KLV_0_KEY (0xffffu << 16) +#define GUC_KLV_0_LEN (0xffffu << 0) +#define GUC_KLV_n_VALUE (0xffffffffu << 0) /** * DOC: GuC Self Config KLVs @@ -101,4 +101,11 @@ GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5, }; +/* + * Workaround keys: + */ +enum { + GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE = 0x9001, +}; + #endif /* _ABI_GUC_KLVS_ABI_H */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -294,6 +294,11 @@ IS_DG2(gt->i915)) flags |= GUC_WA_HOLD_CCS_SWITCHOUT; + /* Wa_16019325821 */ + /* Wa_14019159160 */ + if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) + flags |= GUC_WA_RCS_CCS_SWITCHOUT; + /* * Wa_14012197797 * Wa_22011391025 --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc.h @@ -204,6 +204,8 @@ struct guc_mmio_reg *ads_regset; /** @ads_golden_ctxt_size: size of the golden contexts in the ADS */ u32 ads_golden_ctxt_size; + /** @ads_waklv_size: size of workaround KLVs */ + u32 ads_waklv_size; /** @ads_capture_size: size of register lists in the ADS used for error capture */ u32 ads_capture_size; /** @ads_engine_usage_size: size of engine usage in the ADS */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c @@ -46,6 +46,10 @@ * +---------------------------------------+ * | padding | * +---------------------------------------+ <== 4K aligned + * | w/a KLVs | + * +---------------------------------------+ + * | padding | + * +---------------------------------------+ <== 4K aligned * | capture lists | * +---------------------------------------+ * | padding | @@ -88,6 +92,11 @@ return PAGE_ALIGN(guc->ads_golden_ctxt_size); } +static u32 guc_ads_waklv_size(struct intel_guc *guc) +{ + return PAGE_ALIGN(guc->ads_waklv_size); +} + static u32 guc_ads_capture_size(struct intel_guc *guc) { return PAGE_ALIGN(guc->ads_capture_size); @@ -113,7 +122,7 @@ return PAGE_ALIGN(offset); } -static u32 guc_ads_capture_offset(struct intel_guc *guc) +static u32 guc_ads_waklv_offset(struct intel_guc *guc) { u32 offset; @@ -123,6 +132,16 @@ return PAGE_ALIGN(offset); } +static u32 guc_ads_capture_offset(struct intel_guc *guc) +{ + u32 offset; + + offset = guc_ads_waklv_offset(guc) + + guc_ads_waklv_size(guc); + + return PAGE_ALIGN(offset); +} + static u32 guc_ads_private_data_offset(struct intel_guc *guc) { u32 offset; @@ -791,6 +810,65 @@ return PAGE_ALIGN(total_size); } +/* Wa_14019159160 */ +static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain) +{ + u32 size; + u32 klv_entry[] = { + /* 16:16 key/length */ + FIELD_PREP(GUC_KLV_0_KEY, GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) | + FIELD_PREP(GUC_KLV_0_LEN, 0), + /* 0 dwords data */ + }; + + size = sizeof(klv_entry); + GEM_BUG_ON(remain < size); + + iosys_map_memcpy_to(&guc->ads_map, offset, klv_entry, size); + + return size; +} + +static void guc_waklv_init(struct intel_guc *guc) +{ + struct intel_gt *gt = guc_to_gt(guc); + u32 offset, addr_ggtt, remain, size; + + if (!intel_uc_uses_guc_submission(>->uc)) + return; + + if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0)) + return; + + GEM_BUG_ON(iosys_map_is_null(&guc->ads_map)); + offset = guc_ads_waklv_offset(guc); + remain = guc_ads_waklv_size(guc); + + /* Wa_14019159160 */ + if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) { + size = guc_waklv_ra_mode(guc, offset, remain); + offset += size; + remain -= size; + } + + size = guc_ads_waklv_size(guc) - remain; + if (!size) + return; + + offset = guc_ads_waklv_offset(guc); + addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset; + + ads_blob_write(guc, ads.wa_klv_addr_lo, addr_ggtt); + ads_blob_write(guc, ads.wa_klv_addr_hi, 0); + ads_blob_write(guc, ads.wa_klv_size, size); +} + +static int guc_prep_waklv(struct intel_guc *guc) +{ + /* Fudge something chunky for now: */ + return PAGE_SIZE; +} + static void __guc_ads_init(struct intel_guc *guc) { struct intel_gt *gt = guc_to_gt(guc); @@ -838,6 +916,9 @@ /* MMIO save/restore list */ guc_mmio_reg_state_init(guc); + /* Workaround KLV list */ + guc_waklv_init(guc); + /* Private Data */ ads_blob_write(guc, ads.private_data, base + guc_ads_private_data_offset(guc)); @@ -881,6 +962,12 @@ return ret; guc->ads_capture_size = ret; + /* And don't forget the workaround KLVs: */ + ret = guc_prep_waklv(guc); + if (ret < 0) + return ret; + guc->ads_waklv_size = ret; + /* Now the total size can be determined: */ size = guc_ads_blob_size(guc); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c @@ -115,6 +115,7 @@ case INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID: case INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID: case INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID: + case INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR: *success = false; return true; } @@ -184,7 +185,7 @@ * in the seconds range. However, there is a limit on how long an * individual wait_for() can wait. So wrap it in a loop. */ - before_freq = intel_rps_read_actual_frequency(&uncore->gt->rps); + before_freq = intel_rps_read_actual_frequency(>->rps); before = ktime_get(); for (count = 0; count < GUC_LOAD_RETRY_LIMIT; count++) { ret = wait_for(guc_load_done(uncore, &status, &success), 1000); @@ -192,7 +193,7 @@ break; guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, status = 0x%08X [0x%02X/%02X]\n", - count, intel_rps_read_actual_frequency(&uncore->gt->rps), status, + count, intel_rps_read_actual_frequency(>->rps), status, REG_FIELD_GET(GS_BOOTROM_MASK, status), REG_FIELD_GET(GS_UKERNEL_MASK, status)); } @@ -204,7 +205,7 @@ u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status); guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = %dMHz, ret = %d\n", - status, delta_ms, intel_rps_read_actual_frequency(&uncore->gt->rps), ret); + status, delta_ms, intel_rps_read_actual_frequency(>->rps), ret); guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n", REG_FIELD_GET(GS_MIA_IN_RESET, status), bootrom, ukernel, @@ -241,6 +242,11 @@ ret = -EPERM; break; + case INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR: + guc_info(guc, "invalid w/a KLV entry\n"); + ret = -EINVAL; + break; + case INTEL_GUC_LOAD_STATUS_HWCONFIG_START: guc_info(guc, "still extracting hwconfig table.\n"); ret = -ETIMEDOUT; @@ -254,11 +260,11 @@ guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n", delta_ms, status, count, ret); guc_warn(guc, "excessive init time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n", - intel_rps_read_actual_frequency(&uncore->gt->rps), before_freq, + intel_rps_read_actual_frequency(>->rps), before_freq, intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt))); } else { guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n", - delta_ms, intel_rps_read_actual_frequency(&uncore->gt->rps), + delta_ms, intel_rps_read_actual_frequency(>->rps), before_freq, status, count, ret); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h @@ -96,8 +96,9 @@ #define GUC_WA_GAM_CREDITS BIT(10) #define GUC_WA_DUAL_QUEUE BIT(11) #define GUC_WA_RCS_RESET_BEFORE_RC6 BIT(13) -#define GUC_WA_CONTEXT_ISOLATION BIT(15) #define GUC_WA_PRE_PARSER BIT(14) +#define GUC_WA_CONTEXT_ISOLATION BIT(15) +#define GUC_WA_RCS_CCS_SWITCHOUT BIT(16) #define GUC_WA_HOLD_CCS_SWITCHOUT BIT(17) #define GUC_WA_POLLCS BIT(18) #define GUC_WA_RCS_REGS_IN_CCS_REGS_LIST BIT(21) @@ -430,7 +431,10 @@ u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES]; u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES]; u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX]; - u32 reserved[14]; + u32 wa_klv_addr_lo; + u32 wa_klv_addr_hi; + u32 wa_klv_size; + u32 reserved[11]; } __packed; /* Engine usage stats */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -4382,7 +4382,13 @@ if (engine->class == COMPUTE_CLASS) if (IS_GFX_GT_IP_STEP(engine->gt, IP_VER(12, 70), STEP_A0, STEP_B0) || IS_DG2(engine->i915)) - engine->flags |= I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT; + engine->flags |= I915_ENGINE_USES_WA_HOLD_SWITCHOUT; + + /* Wa_16019325821 */ + /* Wa_14019159160 */ + if ((engine->class == COMPUTE_CLASS || engine->class == RENDER_CLASS) && + IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71))) + engine->flags |= I915_ENGINE_USES_WA_HOLD_SWITCHOUT; /* * TODO: GuC supports timeslicing and semaphores as well, but they're --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -6,6 +6,7 @@ #include #include "gt/intel_gt.h" +#include "gt/intel_rps.h" #include "intel_guc_reg.h" #include "intel_huc.h" #include "intel_huc_print.h" @@ -447,17 +448,68 @@ return partial ? "clear media" : "all workloads"; } +/* + * Use a longer timeout for debug builds so that problems can be detected + * and analysed. But a shorter timeout for releases so that user's don't + * wait forever to find out there is a problem. Note that the only reason + * an end user should hit the timeout is in case of extreme thermal throttling. + * And a system that is that hot during boot is probably dead anyway! + */ +#if defined(CONFIG_DRM_I915_DEBUG_GEM) +#define HUC_LOAD_RETRY_LIMIT 20 +#else +#define HUC_LOAD_RETRY_LIMIT 3 +#endif + int intel_huc_wait_for_auth_complete(struct intel_huc *huc, enum intel_huc_authentication_type type) { struct intel_gt *gt = huc_to_gt(huc); - int ret; - - ret = __intel_wait_for_register(gt->uncore, - huc->status[type].reg, - huc->status[type].mask, - huc->status[type].value, - 2, 50, NULL); + struct intel_uncore *uncore = gt->uncore; + ktime_t before, after, delta; + int ret, count; + u64 delta_ms; + u32 before_freq; + + /* + * The KMD requests maximum frequency during driver load, however thermal + * throttling can force the frequency down to minimum (although the board + * really should never get that hot in real life!). IFWI issues have been + * seen to cause sporadic failures to grant the higher frequency. And at + * minimum frequency, the authentication time can be in the seconds range. + * Note that there is a limit on how long an individual wait_for() can wait. + * So wrap it in a loop. + */ + before_freq = intel_rps_read_actual_frequency(>->rps); + before = ktime_get(); + for (count = 0; count < HUC_LOAD_RETRY_LIMIT; count++) { + ret = __intel_wait_for_register(gt->uncore, + huc->status[type].reg, + huc->status[type].mask, + huc->status[type].value, + 2, 1000, NULL); + if (!ret) + break; + + huc_dbg(huc, "auth still in progress, count = %d, freq = %dMHz, status = 0x%08X\n", + count, intel_rps_read_actual_frequency(>->rps), + huc->status[type].reg.reg); + } + after = ktime_get(); + delta = ktime_sub(after, before); + delta_ms = ktime_to_ms(delta); + + if (delta_ms > 50) { + huc_warn(huc, "excessive auth time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n", + delta_ms, huc->status[type].reg.reg, count, ret); + huc_warn(huc, "excessive auth time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n", + intel_rps_read_actual_frequency(>->rps), before_freq, + intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt))); + } else { + huc_dbg(huc, "auth took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n", + delta_ms, intel_rps_read_actual_frequency(>->rps), + before_freq, huc->status[type].reg.reg, count, ret); + } /* mark the load process as complete even if the wait failed */ delayed_huc_load_complete(huc); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_driver.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_driver.c @@ -799,7 +799,7 @@ goto out_cleanup_modeset2; ret = intel_pxp_init(i915); - if (ret != -ENODEV) + if (ret && ret != -ENODEV) drm_dbg(&i915->drm, "pxp init failed with %d\n", ret); ret = intel_display_driver_probe(i915); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_hwmon.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_hwmon.c @@ -72,12 +72,13 @@ struct intel_uncore *uncore = ddat->uncore; intel_wakeref_t wakeref; - mutex_lock(&hwmon->hwmon_lock); + with_intel_runtime_pm(uncore->rpm, wakeref) { + mutex_lock(&hwmon->hwmon_lock); - with_intel_runtime_pm(uncore->rpm, wakeref) intel_uncore_rmw(uncore, reg, clear, set); - mutex_unlock(&hwmon->hwmon_lock); + mutex_unlock(&hwmon->hwmon_lock); + } } /* @@ -136,20 +137,21 @@ else rgaddr = hwmon->rg.energy_status_all; - mutex_lock(&hwmon->hwmon_lock); + with_intel_runtime_pm(uncore->rpm, wakeref) { + mutex_lock(&hwmon->hwmon_lock); - with_intel_runtime_pm(uncore->rpm, wakeref) reg_val = intel_uncore_read(uncore, rgaddr); - if (reg_val >= ei->reg_val_prev) - ei->accum_energy += reg_val - ei->reg_val_prev; - else - ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val; - ei->reg_val_prev = reg_val; + if (reg_val >= ei->reg_val_prev) + ei->accum_energy += reg_val - ei->reg_val_prev; + else + ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val; + ei->reg_val_prev = reg_val; - *energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY, - hwmon->scl_shift_energy); - mutex_unlock(&hwmon->hwmon_lock); + *energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY, + hwmon->scl_shift_energy); + mutex_unlock(&hwmon->hwmon_lock); + } } static ssize_t @@ -404,6 +406,7 @@ /* Block waiting for GuC reset to complete when needed */ for (;;) { + wakeref = intel_runtime_pm_get(ddat->uncore->rpm); mutex_lock(&hwmon->hwmon_lock); prepare_to_wait(&ddat->waitq, &wait, TASK_INTERRUPTIBLE); @@ -417,14 +420,13 @@ } mutex_unlock(&hwmon->hwmon_lock); + intel_runtime_pm_put(ddat->uncore->rpm, wakeref); schedule(); } finish_wait(&ddat->waitq, &wait); if (ret) - goto unlock; - - wakeref = intel_runtime_pm_get(ddat->uncore->rpm); + goto exit; /* Disable PL1 limit and verify, because the limit cannot be disabled on all platforms */ if (val == PL1_DISABLE) { @@ -444,9 +446,8 @@ intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit, PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1, nval); exit: - intel_runtime_pm_put(ddat->uncore->rpm, wakeref); -unlock: mutex_unlock(&hwmon->hwmon_lock); + intel_runtime_pm_put(ddat->uncore->rpm, wakeref); return ret; } @@ -792,7 +793,7 @@ if (!IS_DGFX(i915)) return; - hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL); + hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); if (!hwmon) return; @@ -818,14 +819,12 @@ hwm_get_preregistration_info(i915); /* hwmon_dev points to device hwmon */ - hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat->name, - ddat, - &hwm_chip_info, - hwm_groups); - if (IS_ERR(hwmon_dev)) { - i915->hwmon = NULL; - return; - } + hwmon_dev = hwmon_device_register_with_info(dev, ddat->name, + ddat, + &hwm_chip_info, + hwm_groups); + if (IS_ERR(hwmon_dev)) + goto err; ddat->hwmon_dev = hwmon_dev; @@ -838,16 +837,36 @@ if (!hwm_gt_is_visible(ddat_gt, hwmon_energy, hwmon_energy_input, 0)) continue; - hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat_gt->name, - ddat_gt, - &hwm_gt_chip_info, - NULL); + hwmon_dev = hwmon_device_register_with_info(dev, ddat_gt->name, + ddat_gt, + &hwm_gt_chip_info, + NULL); if (!IS_ERR(hwmon_dev)) ddat_gt->hwmon_dev = hwmon_dev; } + return; +err: + i915_hwmon_unregister(i915); } void i915_hwmon_unregister(struct drm_i915_private *i915) { - fetch_and_zero(&i915->hwmon); + struct i915_hwmon *hwmon = i915->hwmon; + struct intel_gt *gt; + int i; + + if (!hwmon) + return; + + for_each_gt(gt, i915, i) + if (hwmon->ddat_gt[i].hwmon_dev) + hwmon_device_unregister(hwmon->ddat_gt[i].hwmon_dev); + + if (hwmon->ddat.hwmon_dev) + hwmon_device_unregister(hwmon->ddat.hwmon_dev); + + mutex_destroy(&hwmon->hwmon_lock); + + kfree(i915->hwmon); + i915->hwmon = NULL; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_perf.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_perf.c @@ -3225,7 +3225,7 @@ struct intel_gt *gt = to_gt(i915); /* Wa_18013179988 */ - if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) { + if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) { intel_wakeref_t wakeref; u32 reg, shift; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_reg.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_reg.h @@ -4597,7 +4597,7 @@ #define MTL_CHICKEN_TRANS(trans) _MMIO_TRANS((trans), \ _MTL_CHICKEN_TRANS_A, \ _MTL_CHICKEN_TRANS_B) -#define PIPE_VBLANK_WITH_DELAY REG_BIT(31) /* ADL/DG2 */ +#define PIPE_VBLANK_WITH_DELAY REG_BIT(31) /* tgl+ */ #define SKL_UNMASK_VBL_TO_PIPE_IN_SRD REG_BIT(30) /* skl+ */ #define HSW_FRAME_START_DELAY_MASK REG_GENMASK(28, 27) #define HSW_FRAME_START_DELAY(x) REG_FIELD_PREP(HSW_FRAME_START_DELAY_MASK, x) @@ -5412,6 +5412,9 @@ #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 #define GEN6_PCODE_DATA1 _MMIO(0x13812C) +#define MTL_PCODE_STOLEN_ACCESS _MMIO(0x138914) +#define STOLEN_ACCESS_ALLOWED 0x1 + /* IVYBRIDGE DPF */ #define GEN7_L3CDERRST1(slice) _MMIO(0xB008 + (slice) * 0x200) /* L3CD Error Status 1 */ #define GEN7_L3CDERRST1_ROW_MASK (0x7ff << 14) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_utils.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_utils.c @@ -8,6 +8,7 @@ #include #include "i915_drv.h" +#include "i915_reg.h" #include "i915_utils.h" #define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details." @@ -125,3 +126,19 @@ /* Running as a guest, we assume the host is enforcing VT'd */ return i915_run_as_guest(); } + +bool i915_direct_stolen_access(struct drm_i915_private *i915) +{ + /* + * Wa_22018444074 + * + * Access via BAR can hang MTL, go directly to GSM/DSM, + * except for VM guests which won't have access to it. + * + * Normally this would not work but on MTL the system firmware + * should have relaxed the access permissions sufficiently. + * 0x138914==0x1 indicates that the firmware has done its job. + */ + return IS_METEORLAKE(i915) && !i915_run_as_guest() && + intel_uncore_read(&i915->uncore, MTL_PCODE_STOLEN_ACCESS) == STOLEN_ACCESS_ALLOWED; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_utils.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_utils.h @@ -391,4 +391,6 @@ bool i915_vtd_active(struct drm_i915_private *i915); +bool i915_direct_stolen_access(struct drm_i915_private *i915); + #endif /* !__I915_UTILS_H */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/i915_vma.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/i915_vma.c @@ -34,6 +34,7 @@ #include "gt/intel_engine.h" #include "gt/intel_engine_heartbeat.h" #include "gt/intel_gt.h" +#include "gt/intel_gt_pm.h" #include "gt/intel_gt_requests.h" #include "gt/intel_tlb.h" @@ -103,12 +104,42 @@ static int __i915_vma_active(struct i915_active *ref) { - return i915_vma_tryget(active_to_vma(ref)) ? 0 : -ENOENT; + struct i915_vma *vma = active_to_vma(ref); + + if (!i915_vma_tryget(vma)) + return -ENOENT; + + /* + * Exclude global GTT VMA from holding a GT wakeref + * while active, otherwise GPU never goes idle. + */ + if (!i915_vma_is_ggtt(vma)) { + /* + * Since we and our _retire() counterpart can be + * called asynchronously, storing a wakeref tracking + * handle inside struct i915_vma is not safe, and + * there is no other good place for that. Hence, + * use untracked variants of intel_gt_pm_get/put(). + */ + intel_gt_pm_get_untracked(vma->vm->gt); + } + + return 0; } static void __i915_vma_retire(struct i915_active *ref) { - i915_vma_put(active_to_vma(ref)); + struct i915_vma *vma = active_to_vma(ref); + + if (!i915_vma_is_ggtt(vma)) { + /* + * Since we can be called from atomic contexts, + * use an async variant of intel_gt_pm_put(). + */ + intel_gt_pm_put_async_untracked(vma->vm->gt); + } + + i915_vma_put(vma); } static struct i915_vma * @@ -1404,7 +1435,7 @@ struct i915_vma_work *work = NULL; struct dma_fence *moving = NULL; struct i915_vma_resource *vma_res = NULL; - intel_wakeref_t wakeref = 0; + intel_wakeref_t wakeref; unsigned int bound; int err; @@ -1424,8 +1455,14 @@ if (err) return err; - if (flags & PIN_GLOBAL) - wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm); + /* + * In case of a global GTT, we must hold a runtime-pm wakeref + * while global PTEs are updated. In other cases, we hold + * the rpm reference while the VMA is active. Since runtime + * resume may require allocations, which are forbidden inside + * vm->mutex, get the first rpm wakeref outside of the mutex. + */ + wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm); if (flags & vma->vm->bind_async_flags) { /* lock VM */ @@ -1561,8 +1598,7 @@ if (work) dma_fence_work_commit_imm(&work->base); err_rpm: - if (wakeref) - intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref); + intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref); if (moving) dma_fence_put(moving); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/i915/soc/intel_dram.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/i915/soc/intel_dram.c @@ -681,6 +681,8 @@ if (ret) return; + drm_dbg_kms(&i915->drm, "Num qgv points %u\n", dram_info->num_qgv_points); + drm_dbg_kms(&i915->drm, "DRAM channels: %u\n", dram_info->num_channels); drm_dbg_kms(&i915->drm, "Watermark level 0 adjustment needed: %s\n", --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/imagination/pvr_fw_mips.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/imagination/pvr_fw_mips.h @@ -7,13 +7,14 @@ #include "pvr_rogue_mips.h" #include +#include #include /* Forward declaration from pvr_gem.h. */ struct pvr_gem_object; -#define PVR_MIPS_PT_PAGE_COUNT ((ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES * ROGUE_MIPSFW_PAGE_SIZE_4K) \ - >> PAGE_SHIFT) +#define PVR_MIPS_PT_PAGE_COUNT DIV_ROUND_UP(ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES * ROGUE_MIPSFW_PAGE_SIZE_4K, PAGE_SIZE) + /** * struct pvr_fw_mips_data - MIPS-specific data */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/imagination/pvr_vm_mips.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/imagination/pvr_vm_mips.c @@ -46,7 +46,7 @@ if (!mips_data) return -ENOMEM; - for (page_nr = 0; page_nr < ARRAY_SIZE(mips_data->pt_pages); page_nr++) { + for (page_nr = 0; page_nr < PVR_MIPS_PT_PAGE_COUNT; page_nr++) { mips_data->pt_pages[page_nr] = alloc_page(GFP_KERNEL | __GFP_ZERO); if (!mips_data->pt_pages[page_nr]) { err = -ENOMEM; @@ -102,7 +102,7 @@ int page_nr; vunmap(mips_data->pt); - for (page_nr = ARRAY_SIZE(mips_data->pt_pages) - 1; page_nr >= 0; page_nr--) { + for (page_nr = PVR_MIPS_PT_PAGE_COUNT - 1; page_nr >= 0; page_nr--) { dma_unmap_page(from_pvr_device(pvr_dev)->dev, mips_data->pt_dma_addr[page_nr], PAGE_SIZE, DMA_TO_DEVICE); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/imx/ipuv3/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/imx/ipuv3/Kconfig @@ -35,7 +35,8 @@ config DRM_IMX_HDMI tristate "Freescale i.MX DRM HDMI" - select DRM_DW_HDMI - depends on DRM_IMX && OF + depends on DRM_DW_HDMI + depends on DRM_IMX + depends on OF help Choose this if you want to use HDMI on i.MX6. --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -72,14 +72,14 @@ int ret; if (!mode) - return -EINVAL; + return 0; ret = of_get_drm_display_mode(np, &imxpd->mode, &imxpd->bus_flags, OF_USE_NATIVE_MODE); if (ret) { drm_mode_destroy(connector->dev, mode); - return ret; + return 0; } drm_mode_copy(mode, &imxpd->mode); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ingenic/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/ingenic/Kconfig @@ -28,8 +28,8 @@ config DRM_INGENIC_DW_HDMI tristate "Ingenic specific support for Synopsys DW HDMI" + depends on DRM_DW_HDMI depends on MACH_JZ4780 - select DRM_DW_HDMI help Choose this option to enable Synopsys DesignWare HDMI based driver. If you want to enable HDMI on Ingenic JZ4780 based SoC, you should --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_bcast.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_bcast.c @@ -43,6 +43,18 @@ } +int lima_bcast_mask_irq(struct lima_ip *ip) +{ + bcast_write(LIMA_BCAST_BROADCAST_MASK, 0); + bcast_write(LIMA_BCAST_INTERRUPT_MASK, 0); + return 0; +} + +int lima_bcast_reset(struct lima_ip *ip) +{ + return lima_bcast_hw_init(ip); +} + int lima_bcast_init(struct lima_ip *ip) { int i; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_bcast.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_bcast.h @@ -13,4 +13,7 @@ void lima_bcast_enable(struct lima_device *dev, int num_pp); +int lima_bcast_mask_irq(struct lima_ip *ip); +int lima_bcast_reset(struct lima_ip *ip); + #endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_gem.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_gem.c @@ -75,29 +75,34 @@ } else { bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); if (!bo->base.sgt) { - sg_free_table(&sgt); - return -ENOMEM; + ret = -ENOMEM; + goto err_out0; } } ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); - if (ret) { - sg_free_table(&sgt); - kfree(bo->base.sgt); - bo->base.sgt = NULL; - return ret; - } + if (ret) + goto err_out1; *bo->base.sgt = sgt; if (vm) { ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT); if (ret) - return ret; + goto err_out2; } bo->heap_size = new_size; return 0; + +err_out2: + dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); +err_out1: + kfree(bo->base.sgt); + bo->base.sgt = NULL; +err_out0: + sg_free_table(&sgt); + return ret; } int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_gp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_gp.c @@ -212,6 +212,13 @@ lima_sched_pipe_task_done(pipe); } +static void lima_gp_task_mask_irq(struct lima_sched_pipe *pipe) +{ + struct lima_ip *ip = pipe->processor[0]; + + gp_write(LIMA_GP_INT_MASK, 0); +} + static int lima_gp_task_recover(struct lima_sched_pipe *pipe) { struct lima_ip *ip = pipe->processor[0]; @@ -317,7 +324,9 @@ void lima_gp_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + devm_free_irq(dev->dev, ip->irq, ip); } int lima_gp_pipe_init(struct lima_device *dev) @@ -344,6 +353,7 @@ pipe->task_error = lima_gp_task_error; pipe->task_mmu_error = lima_gp_task_mmu_error; pipe->task_recover = lima_gp_task_recover; + pipe->task_mask_irq = lima_gp_task_mask_irq; return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_mmu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_mmu.c @@ -118,7 +118,12 @@ void lima_mmu_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + if (ip->id == lima_ip_ppmmu_bcast) + return; + + devm_free_irq(dev->dev, ip->irq, ip); } void lima_mmu_flush_tlb(struct lima_ip *ip) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_pp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_pp.c @@ -266,7 +266,9 @@ void lima_pp_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + devm_free_irq(dev->dev, ip->irq, ip); } int lima_pp_bcast_resume(struct lima_ip *ip) @@ -299,7 +301,9 @@ void lima_pp_bcast_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + devm_free_irq(dev->dev, ip->irq, ip); } static int lima_pp_task_validate(struct lima_sched_pipe *pipe, @@ -408,6 +412,9 @@ lima_pp_hard_reset(ip); } + + if (pipe->bcast_processor) + lima_bcast_reset(pipe->bcast_processor); } static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) @@ -416,6 +423,20 @@ lima_sched_pipe_task_done(pipe); } +static void lima_pp_task_mask_irq(struct lima_sched_pipe *pipe) +{ + int i; + + for (i = 0; i < pipe->num_processor; i++) { + struct lima_ip *ip = pipe->processor[i]; + + pp_write(LIMA_PP_INT_MASK, 0); + } + + if (pipe->bcast_processor) + lima_bcast_mask_irq(pipe->bcast_processor); +} + static struct kmem_cache *lima_pp_task_slab; static int lima_pp_task_slab_refcnt; @@ -447,6 +468,7 @@ pipe->task_fini = lima_pp_task_fini; pipe->task_error = lima_pp_task_error; pipe->task_mmu_error = lima_pp_task_mmu_error; + pipe->task_mask_irq = lima_pp_task_mask_irq; return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_sched.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_sched.c @@ -402,6 +402,13 @@ struct lima_sched_task *task = to_lima_task(job); struct lima_device *ldev = pipe->ldev; + /* + * The task might still finish while this timeout handler runs. + * To prevent a race condition on its completion, mask all irqs + * on the running core until the next hard reset completes. + */ + pipe->task_mask_irq(pipe); + if (!pipe->error) DRM_ERROR("lima job timeout\n"); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/lima/lima_sched.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/lima/lima_sched.h @@ -80,6 +80,7 @@ void (*task_error)(struct lima_sched_pipe *pipe); void (*task_mmu_error)(struct lima_sched_pipe *pipe); int (*task_recover)(struct lima_sched_pipe *pipe); + void (*task_mask_irq)(struct lima_sched_pipe *pipe); struct work_struct recover_work; }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_dp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/mediatek/mtk_dp.c @@ -2095,7 +2095,7 @@ if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP && !mtk_dp->train_info.cable_plugged_in) { - ret = -EAGAIN; + ret = -EIO; goto err; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -95,11 +95,13 @@ struct drm_crtc *crtc = &mtk_crtc->base; unsigned long flags; - spin_lock_irqsave(&crtc->dev->event_lock, flags); - drm_crtc_send_vblank_event(crtc, mtk_crtc->event); - drm_crtc_vblank_put(crtc); - mtk_crtc->event = NULL; - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + if (mtk_crtc->event) { + spin_lock_irqsave(&crtc->dev->event_lock, flags); + drm_crtc_send_vblank_event(crtc, mtk_crtc->event); + drm_crtc_vblank_put(crtc); + mtk_crtc->event = NULL; + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + } } static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) @@ -990,10 +992,10 @@ mtk_crtc->mmsys_dev = priv->mmsys_dev; mtk_crtc->ddp_comp_nr = path_len; - mtk_crtc->ddp_comp = devm_kmalloc_array(dev, - mtk_crtc->ddp_comp_nr + (conn_routes ? 1 : 0), - sizeof(*mtk_crtc->ddp_comp), - GFP_KERNEL); + mtk_crtc->ddp_comp = devm_kcalloc(dev, + mtk_crtc->ddp_comp_nr + (conn_routes ? 1 : 0), + sizeof(*mtk_crtc->ddp_comp), + GFP_KERNEL); if (!mtk_crtc->ddp_comp) return -ENOMEM; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -948,6 +948,13 @@ of_node_put(private->comp_node[i]); } +static void mtk_drm_shutdown(struct platform_device *pdev) +{ + struct mtk_drm_private *private = platform_get_drvdata(pdev); + + drm_atomic_helper_shutdown(private->drm); +} + static int mtk_drm_sys_prepare(struct device *dev) { struct mtk_drm_private *private = dev_get_drvdata(dev); @@ -979,6 +986,7 @@ static struct platform_driver mtk_drm_platform_driver = { .probe = mtk_drm_probe, .remove_new = mtk_drm_remove, + .shutdown = mtk_drm_shutdown, .driver = { .name = "mediatek-drm", .pm = &mtk_drm_pm_ops, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -38,6 +38,9 @@ size = round_up(size, PAGE_SIZE); + if (size == 0) + return ERR_PTR(-EINVAL); + mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL); if (!mtk_gem_obj) return ERR_PTR(-ENOMEM); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_dsi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -71,8 +71,8 @@ #define DSI_PS_WC 0x3fff #define DSI_PS_SEL (3 << 16) #define PACKED_PS_16BIT_RGB565 (0 << 16) -#define LOOSELY_PS_18BIT_RGB666 (1 << 16) -#define PACKED_PS_18BIT_RGB666 (2 << 16) +#define PACKED_PS_18BIT_RGB666 (1 << 16) +#define LOOSELY_PS_24BIT_RGB666 (2 << 16) #define PACKED_PS_24BIT_RGB888 (3 << 16) #define DSI_VSA_NL 0x20 @@ -369,10 +369,10 @@ ps_bpp_mode |= PACKED_PS_24BIT_RGB888; break; case MIPI_DSI_FMT_RGB666: - ps_bpp_mode |= PACKED_PS_18BIT_RGB666; + ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666; break; case MIPI_DSI_FMT_RGB666_PACKED: - ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666; + ps_bpp_mode |= PACKED_PS_18BIT_RGB666; break; case MIPI_DSI_FMT_RGB565: ps_bpp_mode |= PACKED_PS_16BIT_RGB565; @@ -426,7 +426,7 @@ dsi_tmp_buf_bpp = 3; break; case MIPI_DSI_FMT_RGB666: - tmp_reg = LOOSELY_PS_18BIT_RGB666; + tmp_reg = LOOSELY_PS_24BIT_RGB666; dsi_tmp_buf_bpp = 3; break; case MIPI_DSI_FMT_RGB666_PACKED: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/meson/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/meson/Kconfig @@ -13,9 +13,9 @@ config DRM_MESON_DW_HDMI tristate "HDMI Synopsys Controller support for Amlogic Meson Display" + depends on DRM_DW_HDMI depends on DRM_MESON default y if DRM_MESON - select DRM_DW_HDMI imply DRM_DW_HDMI_I2S_AUDIO config DRM_MESON_DW_MIPI_DSI --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -106,6 +106,8 @@ #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */ #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */ #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ +#define PHY_CNTL1_INIT 0x03900000 +#define PHY_INVERT BIT(17) #define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ #define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ @@ -130,6 +132,8 @@ unsigned int addr); void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi, unsigned int addr, unsigned int data); + u32 cntl0_init; + u32 cntl1_init; }; struct meson_dw_hdmi { @@ -384,26 +388,6 @@ dw_hdmi_bus_fmt_is_420(hdmi)) mode_is_420 = true; - /* Enable clocks */ - regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); - - /* Bring HDMITX MEM output of power down */ - regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0); - - /* Bring out of reset */ - dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0); - - /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */ - dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, - 0x3, 0x3); - - /* Enable cec_clk and hdcp22_tmdsclk_en */ - dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL, - 0x3 << 4, 0x3 << 4); - - /* Enable normal output to PHY */ - dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); - /* TMDS pattern setup */ if (mode->clock > 340000 && !mode_is_420) { dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, @@ -425,20 +409,6 @@ /* Setup PHY parameters */ meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420); - /* Setup PHY */ - regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, - 0xffff << 16, 0x0390 << 16); - - /* BIT_INVERT */ - if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") || - dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") || - dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi")) - regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, - BIT(17), 0); - else - regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, - BIT(17), BIT(17)); - /* Disable clock, fifo, fifo_wr */ regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); @@ -492,7 +462,9 @@ DRM_DEBUG_DRIVER("\n"); - regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); + /* Fallback to init mode */ + regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init); + regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init); } static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, @@ -610,11 +582,22 @@ .fast_io = true, }; -static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = { +static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = { .top_read = dw_hdmi_top_read, .top_write = dw_hdmi_top_write, .dwc_read = dw_hdmi_dwc_read, .dwc_write = dw_hdmi_dwc_write, + .cntl0_init = 0x0, + .cntl1_init = PHY_CNTL1_INIT | PHY_INVERT, +}; + +static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = { + .top_read = dw_hdmi_top_read, + .top_write = dw_hdmi_top_write, + .dwc_read = dw_hdmi_dwc_read, + .dwc_write = dw_hdmi_dwc_write, + .cntl0_init = 0x0, + .cntl1_init = PHY_CNTL1_INIT, }; static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { @@ -622,6 +605,8 @@ .top_write = dw_hdmi_g12a_top_write, .dwc_read = dw_hdmi_g12a_dwc_read, .dwc_write = dw_hdmi_g12a_dwc_write, + .cntl0_init = 0x000b4242, /* Bandgap */ + .cntl1_init = PHY_CNTL1_INIT, }; static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) @@ -656,6 +641,13 @@ meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_CLK_CNTL, 0xff); + /* Enable normal output to PHY */ + meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12)); + + /* Setup PHY */ + regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init); + regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init); + /* Enable HDMI-TX Interrupt */ meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, HDMITX_TOP_INTR_CORE); @@ -865,11 +857,11 @@ static const struct of_device_id meson_dw_hdmi_of_table[] = { { .compatible = "amlogic,meson-gxbb-dw-hdmi", - .data = &meson_dw_hdmi_gx_data }, + .data = &meson_dw_hdmi_gxbb_data }, { .compatible = "amlogic,meson-gxl-dw-hdmi", - .data = &meson_dw_hdmi_gx_data }, + .data = &meson_dw_hdmi_gxl_data }, { .compatible = "amlogic,meson-gxm-dw-hdmi", - .data = &meson_dw_hdmi_gx_data }, + .data = &meson_dw_hdmi_gxl_data }, { .compatible = "amlogic,meson-g12a-dw-hdmi", .data = &meson_dw_hdmi_g12a_data }, { } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c @@ -95,6 +95,7 @@ return ret; } + clk_disable_unprepare(mipi_dsi->px_clk); ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->mode->clock * 1000); if (ret) { @@ -103,6 +104,12 @@ return ret; } + ret = clk_prepare_enable(mipi_dsi->px_clk); + if (ret) { + dev_err(mipi_dsi->dev, "Failed to enable DSI Pixel clock (ret %d)\n", ret); + return ret; + } + switch (mipi_dsi->dsi_device->format) { case MIPI_DSI_FMT_RGB888: dpi_data_format = DPI_COLOR_24BIT; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/meson/meson_vclk.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/meson/meson_vclk.c @@ -790,13 +790,13 @@ FREQ_1000_1001(params[i].pixel_freq)); DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n", i, params[i].phy_freq, - FREQ_1000_1001(params[i].phy_freq/10)*10); + FREQ_1000_1001(params[i].phy_freq/1000)*1000); /* Match strict frequency */ if (phy_freq == params[i].phy_freq && vclk_freq == params[i].vclk_freq) return MODE_OK; /* Match 1000/1001 variant */ - if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) && + if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) && vclk_freq == FREQ_1000_1001(params[i].vclk_freq)) return MODE_OK; } @@ -1070,7 +1070,7 @@ for (freq = 0 ; params[freq].pixel_freq ; ++freq) { if ((phy_freq == params[freq].phy_freq || - phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) && + phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) && (vclk_freq == params[freq].vclk_freq || vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) { if (vclk_freq != params[freq].vclk_freq) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -284,7 +284,7 @@ a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx); - get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), + get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), rbmemptr_stats(ring, index, cpcycles_start)); get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER, rbmemptr_stats(ring, index, alwayson_start)); @@ -330,7 +330,7 @@ OUT_PKT7(ring, CP_SET_MARKER, 1); OUT_RING(ring, 0x00e); /* IB1LIST end */ - get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), + get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), rbmemptr_stats(ring, index, cpcycles_end)); get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER, rbmemptr_stats(ring, index, alwayson_end)); @@ -1292,9 +1292,12 @@ gpu->ubwc_config.ubwc_mode = 1; } - /* a618 is using the hw default values */ if (adreno_is_a618(gpu)) - return; + gpu->ubwc_config.highest_bank_bit = 14; + + if (adreno_is_a619(gpu)) + /* TODO: Should be 14 but causes corruption at e.g. 1920x1200 on DP */ + gpu->ubwc_config.highest_bank_bit = 13; if (adreno_is_a619_holi(gpu)) gpu->ubwc_config.highest_bank_bit = 13; @@ -2427,7 +2430,7 @@ msm_devfreq_resume(gpu); - adreno_is_a7xx(adreno_gpu) ? a7xx_llc_activate : a6xx_llc_activate(a6xx_gpu); + adreno_is_a7xx(adreno_gpu) ? a7xx_llc_activate(a6xx_gpu) : a6xx_llc_activate(a6xx_gpu); return ret; } @@ -2886,7 +2889,8 @@ ret = a6xx_set_supported_hw(&pdev->dev, config->info); if (ret) { - a6xx_destroy(&(a6xx_gpu->base.base)); + a6xx_llc_slices_destroy(a6xx_gpu); + kfree(a6xx_gpu); return ERR_PTR(ret); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -459,15 +459,15 @@ &perf->core_clk_rate); debugfs_create_u32("enable_bw_release", 0600, entry, (u32 *)&perf->enable_bw_release); - debugfs_create_u32("threshold_low", 0600, entry, + debugfs_create_u32("threshold_low", 0400, entry, (u32 *)&perf->perf_cfg->max_bw_low); - debugfs_create_u32("threshold_high", 0600, entry, + debugfs_create_u32("threshold_high", 0400, entry, (u32 *)&perf->perf_cfg->max_bw_high); - debugfs_create_u32("min_core_ib", 0600, entry, + debugfs_create_u32("min_core_ib", 0400, entry, (u32 *)&perf->perf_cfg->min_core_ib); - debugfs_create_u32("min_llcc_ib", 0600, entry, + debugfs_create_u32("min_llcc_ib", 0400, entry, (u32 *)&perf->perf_cfg->min_llcc_ib); - debugfs_create_u32("min_dram_ib", 0600, entry, + debugfs_create_u32("min_dram_ib", 0400, entry, (u32 *)&perf->perf_cfg->min_dram_ib); debugfs_create_file("perf_mode", 0600, entry, (u32 *)perf, &dpu_core_perf_mode_fops); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -226,6 +226,13 @@ return dpu_enc->wide_bus_en; } +bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc) +{ + const struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); + + return dpu_enc->dsc ? true : false; +} + int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -1853,7 +1860,9 @@ dsc_common_mode = 0; pic_width = dsc->pic_width; - dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL; + dsc_common_mode = DSC_MODE_SPLIT_PANEL; + if (dpu_encoder_use_dsc_merge(enc_master->parent)) + dsc_common_mode |= DSC_MODE_MULTIPLEX; if (enc_master->intf_mode == INTF_MODE_VIDEO) dsc_common_mode |= DSC_MODE_VIDEO; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -159,6 +159,13 @@ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc); /** + * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled + * for the encoder. + * @drm_enc: Pointer to previously created drm encoder structure + */ +bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc); + +/** * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained * in virtual encoder that can collect CRC values * @drm_enc: Pointer to previously created drm encoder structure --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -451,9 +451,6 @@ _dpu_encoder_phys_cmd_pingpong_config(phys_enc); - if (!dpu_encoder_phys_cmd_is_master(phys_enc)) - return; - ctl = phys_enc->hw_ctl; ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -102,6 +102,7 @@ } timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent); /* * for DP, divide the horizonal parameters by 2 when @@ -259,12 +260,14 @@ mode.htotal >>= 1; mode.hsync_start >>= 1; mode.hsync_end >>= 1; + mode.hskew >>= 1; DPU_DEBUG_VIDENC(phys_enc, - "split_role %d, halve horizontal %d %d %d %d\n", + "split_role %d, halve horizontal %d %d %d %d %d\n", phys_enc->split_role, mode.hdisplay, mode.htotal, - mode.hsync_start, mode.hsync_end); + mode.hsync_start, mode.hsync_end, + mode.hskew); } drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c @@ -186,7 +186,7 @@ dpu_hw_cdm_setup_cdwn(ctx, cdm); if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) { - if (fmt->chroma_sample != DPU_CHROMA_H1V2) + if (fmt->chroma_sample == DPU_CHROMA_H1V2) return -EINVAL; /*unsupported format */ opmode = CDM_HDMI_PACK_OP_MODE_EN; opmode |= (fmt->chroma_sample << 1); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -532,6 +532,7 @@ { struct dpu_hw_blk_reg_map *c = &ctx->hw; u32 intf_active = 0; + u32 dsc_active = 0; u32 wb_active = 0; u32 mode_sel = 0; @@ -547,6 +548,7 @@ intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE); + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); if (cfg->intf) intf_active |= BIT(cfg->intf - INTF_0); @@ -554,17 +556,18 @@ if (cfg->wb) wb_active |= BIT(cfg->wb - WB_0); + if (cfg->dsc) + dsc_active |= cfg->dsc; + DPU_REG_WRITE(c, CTL_TOP, mode_sel); DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); if (cfg->merge_3d) DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); - if (cfg->dsc) - DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); - if (cfg->cdm) DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -223,9 +223,11 @@ VERB("IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); - if (!irq_entry->cb) + if (!irq_entry->cb) { DRM_ERROR("no registered cb, IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); + return; + } atomic_inc(&irq_entry->count); @@ -525,14 +527,14 @@ int ret; if (!irq_cb) { - DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", - DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); + DPU_ERROR("IRQ=[%d, %d] NULL callback\n", + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); return -EINVAL; } if (!dpu_core_irq_is_valid(irq_idx)) { - DPU_ERROR("invalid IRQ=[%d, %d]\n", - DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx)); + DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n", + DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb); return -EINVAL; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -163,13 +163,8 @@ hsync_ctl = (hsync_period << 16) | p->hsync_pulse_width; display_hctl = (hsync_end_x << 16) | hsync_start_x; - /* - * DATA_HCTL_EN controls data timing which can be different from - * video timing. It is recommended to enable it for all cases, except - * if compression is enabled in 1 pixel per clock mode - */ if (p->wide_bus_en) - intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN | INTF_CFG2_DATA_HCTL_EN; + intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN; data_width = p->width; @@ -229,6 +224,14 @@ DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg); DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format); if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) { + /* + * DATA_HCTL_EN controls data timing which can be different from + * video timing. It is recommended to enable it for all cases, except + * if compression is enabled in 1 pixel per clock mode + */ + if (!(p->compression_en && !p->wide_bus_en)) + intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN; + DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2); DPU_REG_WRITE(c, INTF_DISPLAY_DATA_HCTL, display_data_hctl); DPU_REG_WRITE(c, INTF_ACTIVE_DATA_HCTL, active_data_hctl); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -33,6 +33,7 @@ u32 hsync_skew; bool wide_bus_en; + bool compression_en; }; struct dpu_hw_intf_prog_fetch { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -374,6 +374,12 @@ return 0; } +static void dpu_kms_global_obj_fini(struct dpu_kms *dpu_kms) +{ + drm_atomic_private_obj_fini(&dpu_kms->global_state); + drm_modeset_lock_fini(&dpu_kms->global_state_lock); +} + static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms) { struct icc_path *path0; @@ -801,6 +807,8 @@ dpu_kms->hw_vbif[i] = NULL; } + dpu_kms_global_obj_fini(dpu_kms); + dpu_kms->catalog = NULL; dpu_kms->hw_mdp = NULL; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_aux.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dp/dp_aux.c @@ -35,6 +35,7 @@ bool no_send_stop; bool initted; bool is_edp; + bool enable_xfers; u32 offset; u32 segment; @@ -302,6 +303,17 @@ } /* + * If we're using DP and an external display isn't connected then the + * transfer won't succeed. Return right away. If we don't do this we + * can end up with long timeouts if someone tries to access the DP AUX + * character device when no DP device is connected. + */ + if (!aux->is_edp && !aux->enable_xfers) { + ret = -ENXIO; + goto exit; + } + + /* * For eDP it's important to give a reasonably long wait here for HPD * to be asserted. This is because the panel driver may have _just_ * turned on the panel and then tried to do an AUX transfer. The panel @@ -433,6 +445,14 @@ return IRQ_HANDLED; } +void dp_aux_enable_xfers(struct drm_dp_aux *dp_aux, bool enabled) +{ + struct dp_aux_private *aux; + + aux = container_of(dp_aux, struct dp_aux_private, dp_aux); + aux->enable_xfers = enabled; +} + void dp_aux_reconfig(struct drm_dp_aux *dp_aux) { struct dp_aux_private *aux; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_aux.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dp/dp_aux.h @@ -12,6 +12,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux); void dp_aux_unregister(struct drm_dp_aux *dp_aux); irqreturn_t dp_aux_isr(struct drm_dp_aux *dp_aux); +void dp_aux_enable_xfers(struct drm_dp_aux *dp_aux, bool enabled); void dp_aux_init(struct drm_dp_aux *dp_aux); void dp_aux_deinit(struct drm_dp_aux *dp_aux); void dp_aux_reconfig(struct drm_dp_aux *dp_aux); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1019,14 +1019,14 @@ if (ret) return ret; - if (voltage_swing_level >= DP_TRAIN_VOLTAGE_SWING_MAX) { + if (voltage_swing_level >= DP_TRAIN_LEVEL_MAX) { drm_dbg_dp(ctrl->drm_dev, "max. voltage swing level reached %d\n", voltage_swing_level); max_level_reached |= DP_TRAIN_MAX_SWING_REACHED; } - if (pre_emphasis_level >= DP_TRAIN_PRE_EMPHASIS_MAX) { + if (pre_emphasis_level >= DP_TRAIN_LEVEL_MAX) { drm_dbg_dp(ctrl->drm_dev, "max. pre-emphasis level reached %d\n", pre_emphasis_level); @@ -1117,7 +1117,7 @@ } if (ctrl->link->phy_params.v_level >= - DP_TRAIN_VOLTAGE_SWING_MAX) { + DP_TRAIN_LEVEL_MAX) { DRM_ERROR_RATELIMITED("max v_level reached\n"); return -EAGAIN; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_display.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dp/dp_display.c @@ -565,6 +565,8 @@ int ret; struct platform_device *pdev = dp->dp_display.pdev; + dp_aux_enable_xfers(dp->aux, true); + mutex_lock(&dp->event_mutex); state = dp->hpd_state; @@ -598,6 +600,7 @@ ret = dp_display_usbpd_configure_cb(&pdev->dev); if (ret) { /* link train failed */ dp->hpd_state = ST_DISCONNECTED; + pm_runtime_put_sync(&pdev->dev); } else { dp->hpd_state = ST_MAINLINK_READY; } @@ -629,6 +632,8 @@ u32 state; struct platform_device *pdev = dp->dp_display.pdev; + dp_aux_enable_xfers(dp->aux, false); + mutex_lock(&dp->event_mutex); state = dp->hpd_state; @@ -655,6 +660,7 @@ dp_display_host_phy_exit(dp); dp->hpd_state = ST_DISCONNECTED; dp_display_notify_disconnect(&dp->dp_display.pdev->dev); + pm_runtime_put_sync(&pdev->dev); mutex_unlock(&dp->event_mutex); return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_link.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dp/dp_link.c @@ -1109,6 +1109,7 @@ int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status) { int i; + u8 max_p_level; int v_max = 0, p_max = 0; struct dp_link_private *link; @@ -1140,30 +1141,29 @@ * Adjust the voltage swing and pre-emphasis level combination to within * the allowable range. */ - if (dp_link->phy_params.v_level > DP_TRAIN_VOLTAGE_SWING_MAX) { + if (dp_link->phy_params.v_level > DP_TRAIN_LEVEL_MAX) { drm_dbg_dp(link->drm_dev, "Requested vSwingLevel=%d, change to %d\n", dp_link->phy_params.v_level, - DP_TRAIN_VOLTAGE_SWING_MAX); - dp_link->phy_params.v_level = DP_TRAIN_VOLTAGE_SWING_MAX; + DP_TRAIN_LEVEL_MAX); + dp_link->phy_params.v_level = DP_TRAIN_LEVEL_MAX; } - if (dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_MAX) { + if (dp_link->phy_params.p_level > DP_TRAIN_LEVEL_MAX) { drm_dbg_dp(link->drm_dev, "Requested preEmphasisLevel=%d, change to %d\n", dp_link->phy_params.p_level, - DP_TRAIN_PRE_EMPHASIS_MAX); - dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_MAX; + DP_TRAIN_LEVEL_MAX); + dp_link->phy_params.p_level = DP_TRAIN_LEVEL_MAX; } - if ((dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_LVL_1) - && (dp_link->phy_params.v_level == - DP_TRAIN_VOLTAGE_SWING_LVL_2)) { + max_p_level = DP_TRAIN_LEVEL_MAX - dp_link->phy_params.v_level; + if (dp_link->phy_params.p_level > max_p_level) { drm_dbg_dp(link->drm_dev, "Requested preEmphasisLevel=%d, change to %d\n", dp_link->phy_params.p_level, - DP_TRAIN_PRE_EMPHASIS_LVL_1); - dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_LVL_1; + max_p_level); + dp_link->phy_params.p_level = max_p_level; } drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n", --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_link.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dp/dp_link.h @@ -19,19 +19,7 @@ unsigned long capabilities; }; -enum dp_link_voltage_level { - DP_TRAIN_VOLTAGE_SWING_LVL_0 = 0, - DP_TRAIN_VOLTAGE_SWING_LVL_1 = 1, - DP_TRAIN_VOLTAGE_SWING_LVL_2 = 2, - DP_TRAIN_VOLTAGE_SWING_MAX = DP_TRAIN_VOLTAGE_SWING_LVL_2, -}; - -enum dp_link_preemaphasis_level { - DP_TRAIN_PRE_EMPHASIS_LVL_0 = 0, - DP_TRAIN_PRE_EMPHASIS_LVL_1 = 1, - DP_TRAIN_PRE_EMPHASIS_LVL_2 = 2, - DP_TRAIN_PRE_EMPHASIS_MAX = DP_TRAIN_PRE_EMPHASIS_LVL_2, -}; +#define DP_TRAIN_LEVEL_MAX 3 struct dp_link_test_video { u32 test_video_pattern; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/dsi/dsi_host.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -366,8 +366,8 @@ { int ret; - DBG("Set clk rates: pclk=%d, byteclk=%lu", - msm_host->mode->clock, msm_host->byte_clk_rate); + DBG("Set clk rates: pclk=%lu, byteclk=%lu", + msm_host->pixel_clk_rate, msm_host->byte_clk_rate); ret = dev_pm_opp_set_rate(&msm_host->pdev->dev, msm_host->byte_clk_rate); @@ -440,9 +440,9 @@ { int ret; - DBG("Set clk rates: pclk=%d, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu", - msm_host->mode->clock, msm_host->byte_clk_rate, - msm_host->esc_clk_rate, msm_host->src_clk_rate); + DBG("Set clk rates: pclk=%lu, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu", + msm_host->pixel_clk_rate, msm_host->byte_clk_rate, + msm_host->esc_clk_rate, msm_host->src_clk_rate); ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate); if (ret) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/msm_fb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/msm_fb.c @@ -89,7 +89,7 @@ for (i = 0; i < n; i++) { ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &msm_fb->iova[i]); - drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)", + drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)\n", fb->base.id, i, msm_fb->iova[i], ret); if (ret) return ret; @@ -176,7 +176,7 @@ const struct msm_format *format; int ret, i, n; - drm_dbg_state(dev, "create framebuffer: mode_cmd=%p (%dx%d@%4.4s)", + drm_dbg_state(dev, "create framebuffer: mode_cmd=%p (%dx%d@%4.4s)\n", mode_cmd, mode_cmd->width, mode_cmd->height, (char *)&mode_cmd->pixel_format); @@ -232,7 +232,7 @@ refcount_set(&msm_fb->dirtyfb, 1); - drm_dbg_state(dev, "create: FB ID: %d (%p)", fb->base.id, fb); + drm_dbg_state(dev, "create: FB ID: %d (%p)\n", fb->base.id, fb); return fb; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/msm/msm_kms.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/msm/msm_kms.c @@ -149,7 +149,7 @@ struct msm_kms *kms = priv->kms; if (!kms) return -ENXIO; - drm_dbg_vbl(dev, "crtc=%u", crtc->base.id); + drm_dbg_vbl(dev, "crtc=%u\n", crtc->base.id); return vblank_ctrl_queue_work(priv, crtc, true); } @@ -160,7 +160,7 @@ struct msm_kms *kms = priv->kms; if (!kms) return; - drm_dbg_vbl(dev, "crtc=%u", crtc->base.id); + drm_dbg_vbl(dev, "crtc=%u\n", crtc->base.id); vblank_ctrl_queue_work(priv, crtc, false); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/mxsfb/lcdif_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/mxsfb/lcdif_drv.c @@ -340,6 +340,9 @@ if (ret) return ret; + if (pm_runtime_suspended(dev)) + return 0; + return lcdif_rpm_suspend(dev); } @@ -347,7 +350,8 @@ { struct drm_device *drm = dev_get_drvdata(dev); - lcdif_rpm_resume(dev); + if (!pm_runtime_suspended(dev)) + lcdif_rpm_resume(dev); return drm_mode_config_helper_resume(drm); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -68,7 +68,7 @@ if (nv_two_heads(dev)) NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0); - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); if (!suspend) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -209,6 +209,8 @@ struct drm_display_mode *mode; mode = drm_mode_duplicate(encoder->dev, tv_mode); + if (!mode) + continue; mode->clock = tv_norm->tv_enc_mode.vrefresh * mode->htotal / 1000 * @@ -258,6 +260,8 @@ if (modes[i].hdisplay == output_mode->hdisplay && modes[i].vdisplay == output_mode->vdisplay) { mode = drm_mode_duplicate(encoder->dev, output_mode); + if (!mode) + continue; mode->type |= DRM_MODE_TYPE_PREFERRED; } else { @@ -265,6 +269,8 @@ modes[i].vdisplay, 60, false, (output_mode->flags & DRM_MODE_FLAG_INTERLACE), false); + if (!mode) + continue; } /* CVT modes are sometimes unsuitable... */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -914,7 +914,7 @@ msto->disabled = false; drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload); } else if (msto->enabled) { - drm_dp_add_payload_part2(mgr, state, new_payload); + drm_dp_add_payload_part2(mgr, new_payload); msto->enabled = false; } } @@ -2679,7 +2679,7 @@ nv50_mstm_fini(nouveau_encoder(encoder)); } - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h @@ -15,7 +15,9 @@ }; struct nvkm_gsp_radix3 { - struct nvkm_gsp_mem mem[3]; + struct nvkm_gsp_mem lvl0; + struct nvkm_gsp_mem lvl1; + struct sg_table lvl2; }; int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -272,6 +272,9 @@ getparam->value = (u64)ttm_resource_manager_usage(vram_mgr); break; } + case NOUVEAU_GETPARAM_HAS_VMA_TILEMODE: + getparam->value = 1; + break; default: NV_PRINTK(dbg, cli, "unknown parameter %lld\n", getparam->param); return -EINVAL; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_bios.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -23,6 +23,7 @@ */ #include "nouveau_drv.h" +#include "nouveau_bios.h" #include "nouveau_reg.h" #include "dispnv04/hw.h" #include "nouveau_encoder.h" @@ -1677,7 +1678,7 @@ */ if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) { if (*conn == 0xf2005014 && *conf == 0xffffffff) { - fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, 1); + fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, DCB_OUTPUT_B); return false; } } @@ -1763,26 +1764,26 @@ #ifdef __powerpc__ /* Apple iMac G4 NV17 */ if (of_machine_is_compatible("PowerMac4,5")) { - fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, 1); - fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, 2); + fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, DCB_OUTPUT_B); + fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, DCB_OUTPUT_C); return; } #endif /* Make up some sane defaults */ fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, - bios->legacy.i2c_indices.crt, 1, 1); + bios->legacy.i2c_indices.crt, 1, DCB_OUTPUT_B); if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) fabricate_dcb_output(dcb, DCB_OUTPUT_TV, bios->legacy.i2c_indices.tv, - all_heads, 0); + all_heads, DCB_OUTPUT_A); else if (bios->tmds.output0_script_ptr || bios->tmds.output1_script_ptr) fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, bios->legacy.i2c_indices.panel, - all_heads, 1); + all_heads, DCB_OUTPUT_B); } static int --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_bo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -241,28 +241,28 @@ } nvbo->contig = !(tile_flags & NOUVEAU_GEM_TILE_NONCONTIG); - if (!nouveau_cli_uvmm(cli) || internal) { - /* for BO noVM allocs, don't assign kinds */ - if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { - nvbo->kind = (tile_flags & 0x0000ff00) >> 8; - if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { - kfree(nvbo); - return ERR_PTR(-EINVAL); - } - nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind; - } else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - nvbo->kind = (tile_flags & 0x00007f00) >> 8; - nvbo->comp = (tile_flags & 0x00030000) >> 16; - if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { - kfree(nvbo); - return ERR_PTR(-EINVAL); - } - } else { - nvbo->zeta = (tile_flags & 0x00000007); + if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) { + nvbo->kind = (tile_flags & 0x0000ff00) >> 8; + if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { + kfree(nvbo); + return ERR_PTR(-EINVAL); + } + + nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind; + } else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { + nvbo->kind = (tile_flags & 0x00007f00) >> 8; + nvbo->comp = (tile_flags & 0x00030000) >> 16; + if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) { + kfree(nvbo); + return ERR_PTR(-EINVAL); } - nvbo->mode = tile_mode; + } else { + nvbo->zeta = (tile_flags & 0x00000007); + } + nvbo->mode = tile_mode; + if (!nouveau_cli_uvmm(cli) || internal) { /* Determine the desirable target GPU page size for the buffer. */ for (i = 0; i < vmm->page_nr; i++) { /* Because we cannot currently allow VMM maps to fail @@ -304,12 +304,6 @@ } nvbo->page = vmm->page[pi].shift; } else { - /* reject other tile flags when in VM mode. */ - if (tile_mode) - return ERR_PTR(-EINVAL); - if (tile_flags & ~NOUVEAU_GEM_TILE_NONCONTIG) - return ERR_PTR(-EINVAL); - /* Determine the desirable target GPU page size for the buffer. */ for (i = 0; i < vmm->page_nr; i++) { /* Because we cannot currently allow VMM maps to fail @@ -1264,6 +1258,8 @@ drm_vma_node_unmap(&nvbo->bo.base.vma_node, bdev->dev_mapping); nouveau_ttm_io_mem_free_locked(drm, nvbo->bo.resource); + nvbo->bo.resource->bus.offset = 0; + nvbo->bo.resource->bus.addr = NULL; goto retry; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_connector.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1001,6 +1001,9 @@ struct drm_display_mode *mode; mode = drm_mode_duplicate(dev, nv_connector->native_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); ret = 1; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_display.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_display.c @@ -450,6 +450,9 @@ { struct nouveau_drm *drm = nouveau_drm(dev); + if (drm->headless) + return; + spin_lock_irq(&drm->hpd_lock); drm->hpd_pending = ~0; spin_unlock_irq(&drm->hpd_lock); @@ -635,7 +638,7 @@ } drm_connector_list_iter_end(&conn_iter); - if (!runtime) + if (!runtime && !drm->headless) cancel_work_sync(&drm->hpd_work); drm_kms_helper_poll_disable(dev); @@ -729,6 +732,7 @@ /* no display hw */ if (ret == -ENODEV) { ret = 0; + drm->headless = true; goto disp_create_err; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -378,9 +378,9 @@ dma_addr_t *dma_addrs; struct nouveau_fence *fence; - src_pfns = kcalloc(npages, sizeof(*src_pfns), GFP_KERNEL); - dst_pfns = kcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL); - dma_addrs = kcalloc(npages, sizeof(*dma_addrs), GFP_KERNEL); + src_pfns = kvcalloc(npages, sizeof(*src_pfns), GFP_KERNEL | __GFP_NOFAIL); + dst_pfns = kvcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL | __GFP_NOFAIL); + dma_addrs = kvcalloc(npages, sizeof(*dma_addrs), GFP_KERNEL | __GFP_NOFAIL); migrate_device_range(src_pfns, chunk->pagemap.range.start >> PAGE_SHIFT, npages); @@ -406,11 +406,11 @@ migrate_device_pages(src_pfns, dst_pfns, npages); nouveau_dmem_fence_done(&fence); migrate_device_finalize(src_pfns, dst_pfns, npages); - kfree(src_pfns); - kfree(dst_pfns); + kvfree(src_pfns); + kvfree(dst_pfns); for (i = 0; i < npages; i++) dma_unmap_page(chunk->drm->dev->dev, dma_addrs[i], PAGE_SIZE, DMA_BIDIRECTIONAL); - kfree(dma_addrs); + kvfree(dma_addrs); } void --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_dp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -225,12 +225,15 @@ u8 *dpcd = nv_encoder->dp.dpcd; int ret = NOUVEAU_DP_NONE, hpd; - /* If we've already read the DPCD on an eDP device, we don't need to - * reread it as it won't change + /* eDP ports don't support hotplugging - so there's no point in probing eDP ports unless we + * haven't probed them once before. */ - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && - dpcd[DP_DPCD_REV] != 0) - return NOUVEAU_DP_SST; + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (connector->status == connector_status_connected) + return NOUVEAU_DP_SST; + else if (connector->status == connector_status_disconnected) + return NOUVEAU_DP_NONE; + } mutex_lock(&nv_encoder->dp.hpd_irq_lock); if (mstm) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_drv.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -276,6 +276,7 @@ /* modesetting */ struct nvbios vbios; struct nouveau_display *display; + bool headless; struct work_struct hpd_work; spinlock_t hpd_lock; u32 hpd_pending; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_uvmm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nouveau_uvmm.c @@ -812,15 +812,15 @@ struct drm_gpuva_op_unmap *u = r->unmap; struct nouveau_uvma *uvma = uvma_from_va(u->va); u64 addr = uvma->va.va.addr; - u64 range = uvma->va.va.range; + u64 end = uvma->va.va.addr + uvma->va.va.range; if (r->prev) addr = r->prev->va.addr + r->prev->va.range; if (r->next) - range = r->next->va.addr - addr; + end = r->next->va.addr; - op_unmap_range(u, addr, range); + op_unmap_range(u, addr, end - addr); } static int --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c @@ -1080,7 +1080,7 @@ ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl)); if (ret) { nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl); - return PTR_ERR(ctrl); + return ret; } memcpy(data, ctrl->data, size); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c @@ -66,11 +66,16 @@ return ERR_PTR(-EINVAL); } +static void of_fini(void *p) +{ + kfree(p); +} + const struct nvbios_source nvbios_of = { .name = "OpenFirmware", .init = of_init, - .fini = (void(*)(void *))kfree, + .fini = of_fini, .read = of_read, .size = of_size, .rw = false, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c @@ -25,6 +25,7 @@ #include #include +#include void gm107_devinit_disable(struct nvkm_devinit *init) @@ -33,10 +34,13 @@ u32 r021c00 = nvkm_rd32(device, 0x021c00); u32 r021c04 = nvkm_rd32(device, 0x021c04); - if (r021c00 & 0x00000001) - nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0); - if (r021c00 & 0x00000004) - nvkm_subdev_disable(device, NVKM_ENGINE_CE, 2); + /* gsp only wants to enable/disable display */ + if (!nvkm_gsp_rm(device->gsp)) { + if (r021c00 & 0x00000001) + nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0); + if (r021c00 & 0x00000004) + nvkm_subdev_disable(device, NVKM_ENGINE_CE, 2); + } if (r021c04 & 0x00000001) nvkm_subdev_disable(device, NVKM_ENGINE_DISP, 0); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c @@ -1112,7 +1112,7 @@ rpc->numEntries = NV_GSP_REG_NUM_ENTRIES; str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]); - strings = (char *)&rpc->entries[NV_GSP_REG_NUM_ENTRIES]; + strings = (char *)rpc + str_offset; for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) { int name_len = strlen(r535_registry_entries[i].name) + 1; @@ -1620,7 +1620,7 @@ meta->magic = GSP_FW_WPR_META_MAGIC; meta->revision = GSP_FW_WPR_META_REVISION; - meta->sysmemAddrOfRadix3Elf = gsp->radix3.mem[0].addr; + meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr; meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size; meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; @@ -1914,8 +1914,9 @@ static void nvkm_gsp_radix3_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_radix3 *rx3) { - for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) - nvkm_gsp_mem_dtor(gsp, &rx3->mem[i]); + nvkm_gsp_sg_free(gsp->subdev.device, &rx3->lvl2); + nvkm_gsp_mem_dtor(gsp, &rx3->lvl1); + nvkm_gsp_mem_dtor(gsp, &rx3->lvl0); } /** @@ -1951,36 +1952,60 @@ nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size, struct nvkm_gsp_radix3 *rx3) { - u64 addr; + struct sg_dma_page_iter sg_dma_iter; + struct scatterlist *sg; + size_t bufsize; + u64 *pte; + int ret, i, page_idx = 0; - for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) { - u64 *ptes; - size_t bufsize; - int ret, idx; + ret = nvkm_gsp_mem_ctor(gsp, GSP_PAGE_SIZE, &rx3->lvl0); + if (ret) + return ret; - bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE); - ret = nvkm_gsp_mem_ctor(gsp, bufsize, &rx3->mem[i]); - if (ret) - return ret; + ret = nvkm_gsp_mem_ctor(gsp, GSP_PAGE_SIZE, &rx3->lvl1); + if (ret) + goto lvl1_fail; - ptes = rx3->mem[i].data; - if (i == 2) { - struct scatterlist *sgl; - - for_each_sgtable_dma_sg(sgt, sgl, idx) { - for (int j = 0; j < sg_dma_len(sgl) / GSP_PAGE_SIZE; j++) - *ptes++ = sg_dma_address(sgl) + (GSP_PAGE_SIZE * j); - } - } else { - for (int j = 0; j < size / GSP_PAGE_SIZE; j++) - *ptes++ = addr + GSP_PAGE_SIZE * j; + // Allocate level 2 + bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE); + ret = nvkm_gsp_sg(gsp->subdev.device, bufsize, &rx3->lvl2); + if (ret) + goto lvl2_fail; + + // Write the bus address of level 1 to level 0 + pte = rx3->lvl0.data; + *pte = rx3->lvl1.addr; + + // Write the bus address of each page in level 2 to level 1 + pte = rx3->lvl1.data; + for_each_sgtable_dma_page(&rx3->lvl2, &sg_dma_iter, 0) + *pte++ = sg_page_iter_dma_address(&sg_dma_iter); + + // Finally, write the bus address of each page in sgt to level 2 + for_each_sgtable_sg(&rx3->lvl2, sg, i) { + void *sgl_end; + + pte = sg_virt(sg); + sgl_end = (void *)pte + sg->length; + + for_each_sgtable_dma_page(sgt, &sg_dma_iter, page_idx) { + *pte++ = sg_page_iter_dma_address(&sg_dma_iter); + page_idx++; + + // Go to the next scatterlist for level 2 if we've reached the end + if ((void *)pte >= sgl_end) + break; } + } - size = rx3->mem[i].size; - addr = rx3->mem[i].addr; + if (ret) { +lvl2_fail: + nvkm_gsp_mem_dtor(gsp, &rx3->lvl1); +lvl1_fail: + nvkm_gsp_mem_dtor(gsp, &rx3->lvl0); } - return 0; + return ret; } int @@ -2012,7 +2037,7 @@ sr = gsp->sr.meta.data; sr->magic = GSP_FW_SR_META_MAGIC; sr->revision = GSP_FW_SR_META_REVISION; - sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.mem[0].addr; + sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr; sr->sizeOfSuspendResumeData = len; mbox0 = lower_32_bits(gsp->sr.meta.addr); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -222,8 +222,11 @@ void __iomem *map = NULL; /* Already mapped? */ - if (refcount_inc_not_zero(&iobj->maps)) + if (refcount_inc_not_zero(&iobj->maps)) { + /* read barrier match the wmb on refcount set */ + smp_rmb(); return iobj->map; + } /* Take the lock, and re-check that another thread hasn't * already mapped the object in the meantime. @@ -250,6 +253,8 @@ iobj->base.memory.ptrs = &nv50_instobj_fast; else iobj->base.memory.ptrs = &nv50_instobj_slow; + /* barrier to ensure the ptrs are written before refcount is set */ + smp_wmb(); refcount_set(&iobj->maps, 1); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/omapdrm/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/omapdrm/Kconfig @@ -4,7 +4,7 @@ depends on DRM && OF depends on ARCH_OMAP2PLUS select DRM_KMS_HELPER - select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION + select FB_DMAMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION select VIDEOMODE_HELPERS select HDMI default n --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -51,6 +51,10 @@ omap_gem_roll(bo, fbi->var.yoffset * npages); } +FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area) + static int omap_fbdev_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { @@ -78,11 +82,9 @@ static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { - struct drm_fb_helper *helper = info->par; - struct drm_framebuffer *fb = helper->fb; - struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0); + vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); - return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma); + return fb_deferred_io_mmap(info, vma); } static void omap_fbdev_fb_destroy(struct fb_info *info) @@ -94,6 +96,7 @@ DBG(); + fb_deferred_io_cleanup(info); drm_fb_helper_fini(helper); omap_gem_unpin(bo); @@ -104,15 +107,19 @@ kfree(fbdev); } +/* + * For now, we cannot use FB_DEFAULT_DEFERRED_OPS and fb_deferred_io_mmap() + * because we use write-combine. + */ static const struct fb_ops omap_fb_ops = { .owner = THIS_MODULE, - __FB_DEFAULT_DMAMEM_OPS_RDWR, + __FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev), .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, .fb_setcmap = drm_fb_helper_setcmap, .fb_blank = drm_fb_helper_blank, .fb_pan_display = omap_fbdev_pan_display, - __FB_DEFAULT_DMAMEM_OPS_DRAW, + __FB_DEFAULT_DEFERRED_OPS_DRAW(omap_fbdev), .fb_ioctl = drm_fb_helper_ioctl, .fb_mmap = omap_fbdev_fb_mmap, .fb_destroy = omap_fbdev_fb_destroy, @@ -213,6 +220,15 @@ fbi->fix.smem_start = dma_addr; fbi->fix.smem_len = bo->size; + /* deferred I/O */ + helper->fbdefio.delay = HZ / 20; + helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; + + fbi->fbdefio = &helper->fbdefio; + ret = fb_deferred_io_init(fbi); + if (ret) + goto fail; + /* if we have DMM, then we can use it for scrolling by just * shuffling pages around in DMM rather than doing sw blit. */ @@ -238,8 +254,20 @@ return ret; } +static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip) +{ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) + return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + + return 0; +} + static const struct drm_fb_helper_funcs omap_fb_helper_funcs = { .fb_probe = omap_fbdev_create, + .fb_dirty = omap_fbdev_dirty, }; static struct drm_fb_helper *get_fb(struct fb_info *fbi) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/Kconfig @@ -184,7 +184,7 @@ config DRM_PANEL_ILITEK_ILI9341 tristate "Ilitek ILI9341 240x320 QVGA panels" - depends on OF && SPI + depends on SPI select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER depends on BACKLIGHT_CLASS_DEVICE --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -1871,6 +1871,8 @@ gpiod_set_value(boe->enable_gpio, 0); + boe->base.prepare_prev_first = true; + drm_panel_init(&boe->base, dev, &boe_panel_funcs, DRM_MODE_CONNECTOR_DSI); err = of_drm_get_panel_orientation(dev->of_node, &boe->orientation); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-edp.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-edp.c @@ -397,6 +397,7 @@ { struct panel_edp *p = dev_get_drvdata(dev); + drm_dp_dpcd_set_powered(p->aux, false); gpiod_set_value_cansleep(p->enable_gpio, 0); regulator_disable(p->supply); p->unprepared_time = ktime_get_boottime(); @@ -413,8 +414,7 @@ if (!p->prepared) return 0; - pm_runtime_mark_last_busy(panel->dev); - ret = pm_runtime_put_autosuspend(panel->dev); + ret = pm_runtime_put_sync_suspend(panel->dev); if (ret < 0) return ret; p->prepared = false; @@ -454,6 +454,7 @@ } gpiod_set_value_cansleep(p->enable_gpio, 1); + drm_dp_dpcd_set_powered(p->aux, true); delay = p->desc->delay.hpd_reliable; if (p->no_hpd) @@ -490,6 +491,7 @@ return 0; error: + drm_dp_dpcd_set_powered(p->aux, false); gpiod_set_value_cansleep(p->enable_gpio, 0); regulator_disable(p->supply); p->unprepared_time = ktime_get_boottime(); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -22,8 +22,9 @@ #include #include #include +#include #include -#include +#include #include #include @@ -421,7 +422,7 @@ ili9341_dpi_init(ili); - return ret; + return 0; } static int ili9341_dpi_enable(struct drm_panel *panel) @@ -691,7 +692,7 @@ * Every new incarnation of this display must have a unique * data entry for the system in this driver. */ - ili->conf = of_device_get_match_data(dev); + ili->conf = device_get_match_data(dev); if (!ili->conf) { dev_err(dev, "missing device configuration\n"); return -ENODEV; @@ -714,18 +715,18 @@ reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset)) - dev_err(dev, "Failed to get gpio 'reset'\n"); + return dev_err_probe(dev, PTR_ERR(reset), "Failed to get gpio 'reset'\n"); dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW); if (IS_ERR(dc)) - dev_err(dev, "Failed to get gpio 'dc'\n"); + return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n"); if (!strcmp(id->name, "sf-tc240t-9370-t")) return ili9341_dpi_probe(spi, dc, reset); else if (!strcmp(id->name, "yx240qv29")) return ili9341_dbi_probe(spi, dc, reset); - return -1; + return -ENODEV; } static void ili9341_remove(struct spi_device *spi) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -1080,10 +1080,10 @@ msleep(5); /* And reset it */ - gpiod_set_value(ctx->reset, 1); + gpiod_set_value_cansleep(ctx->reset, 1); msleep(20); - gpiod_set_value(ctx->reset, 0); + gpiod_set_value_cansleep(ctx->reset, 0); msleep(20); for (i = 0; i < ctx->desc->init_length; i++) { @@ -1138,7 +1138,7 @@ mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); regulator_disable(ctx->power); - gpiod_set_value(ctx->reset, 1); + gpiod_set_value_cansleep(ctx->reset, 1); return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c @@ -295,8 +295,6 @@ mipi_dsi_dcs_write_seq(dsi, 0xbd, 0x00); mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xef); mipi_dsi_dcs_write_seq(dsi, 0xd4, 0x02); - mipi_dsi_dcs_write_seq(dsi, 0x11); - mipi_dsi_dcs_write_seq(dsi, 0x29); ret = mipi_dsi_dcs_set_tear_on(dsi, 1); if (ret < 0) { @@ -326,7 +324,8 @@ static const struct ltk050h3146w_desc ltk050h3148w_data = { .mode = <k050h3148w_mode, .init = ltk050h3148w_init_sequence, - .mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_BURST, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_VIDEO_BURST, }; static int ltk050h3146w_init_sequence(struct ltk050h3146w *ctx) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-novatek-nt35950.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-novatek-nt35950.c @@ -556,10 +556,8 @@ } dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r); of_node_put(dsi_r); - if (!dsi_r_host) { - dev_err(dev, "Cannot get secondary DSI host\n"); - return -EPROBE_DEFER; - } + if (!dsi_r_host) + return dev_err_probe(dev, -EPROBE_DEFER, "Cannot get secondary DSI host\n"); nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info); if (!nt->dsi[1]) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c @@ -72,6 +72,7 @@ if (p->el3_was_on) atana33xc20_wait(p->el_on3_off_time, 150); + drm_dp_dpcd_set_powered(p->aux, false); ret = regulator_disable(p->supply); if (ret) return ret; @@ -93,6 +94,7 @@ ret = regulator_enable(p->supply); if (ret) return ret; + drm_dp_dpcd_set_powered(p->aux, true); p->powered_on_time = ktime_get_boottime(); if (p->no_hpd) { @@ -107,19 +109,17 @@ if (hpd_asserted < 0) ret = hpd_asserted; - if (ret) + if (ret) { dev_warn(dev, "Error waiting for HPD GPIO: %d\n", ret); - - return ret; - } - - if (p->aux->wait_hpd_asserted) { + goto error; + } + } else if (p->aux->wait_hpd_asserted) { ret = p->aux->wait_hpd_asserted(p->aux, HPD_MAX_US); - if (ret) + if (ret) { dev_warn(dev, "Controller error waiting for HPD: %d\n", ret); - - return ret; + goto error; + } } /* @@ -131,6 +131,12 @@ * right times. */ return 0; + +error: + drm_dp_dpcd_set_powered(p->aux, false); + regulator_disable(p->supply); + + return ret; } static int atana33xc20_disable(struct drm_panel *panel) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-simple.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-simple.c @@ -1367,6 +1367,23 @@ .vtotal = 800 + 6 + 8 + 2, }; +static const struct panel_desc boe_bp082wx1_100 = { + .modes = &boe_bp101wx1_100_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 177, + .height = 110, + }, + .delay = { + .enable = 50, + .disable = 50, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct panel_desc boe_bp101wx1_100 = { .modes = &boe_bp101wx1_100_mode, .num_modes = 1, @@ -2547,6 +2564,9 @@ .unprepare = 200, .disable = 400, }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing innolux_g156hce_l01_timings = { @@ -2660,6 +2680,7 @@ .vfront_porch = { 3, 5, 10 }, .vback_porch = { 2, 5, 10 }, .vsync_len = { 5, 5, 5 }, + .flags = DISPLAY_FLAGS_DE_HIGH, }; static const struct panel_desc koe_tx26d202vm0bwa = { @@ -4346,6 +4367,9 @@ .compatible = "bananapi,s070wv20-ct16", .data = &bananapi_s070wv20_ct16, }, { + .compatible = "boe,bp082wx1-100", + .data = &boe_bp082wx1_100, + }, { .compatible = "boe,bp101wx1-100", .data = &boe_bp101wx1_100, }, { @@ -4780,6 +4804,33 @@ .lanes = 4, }; +static const struct drm_display_mode auo_b101uan01_mode = { + .clock = 154500, + .hdisplay = 1920, + .hsync_start = 1920 + 185, + .hsync_end = 1920 + 185, + .htotal = 1920 + 185 + 925, + .vdisplay = 1200, + .vsync_start = 1200 + 3, + .vsync_end = 1200 + 3 + 5, + .vtotal = 1200 + 3 + 5 + 4, +}; + +static const struct panel_desc_dsi auo_b101uan01 = { + .desc = { + .modes = &auo_b101uan01_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 108, + .height = 272, + }, + }, + .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE, + .format = MIPI_DSI_FMT_RGB888, + .lanes = 4, +}; + static const struct drm_display_mode boe_tv080wum_nl0_mode = { .clock = 160000, .hdisplay = 1200, @@ -4959,6 +5010,9 @@ .compatible = "auo,b080uan01", .data = &auo_b080uan01 }, { + .compatible = "auo,b101uan01", + .data = &auo_b101uan01 + }, { .compatible = "boe,tv080wum-nl0", .data = &boe_tv080wum_nl0 }, { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-sitronix-st7789v.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-sitronix-st7789v.c @@ -282,15 +282,15 @@ static const struct drm_display_mode jt240mhqs_hwt_ek_e3_mode = { .clock = 6000, .hdisplay = 240, - .hsync_start = 240 + 28, - .hsync_end = 240 + 28 + 10, - .htotal = 240 + 28 + 10 + 10, + .hsync_start = 240 + 38, + .hsync_end = 240 + 38 + 10, + .htotal = 240 + 38 + 10 + 10, .vdisplay = 280, - .vsync_start = 280 + 8, - .vsync_end = 280 + 8 + 4, - .vtotal = 280 + 8 + 4 + 4, - .width_mm = 43, - .height_mm = 37, + .vsync_start = 280 + 48, + .vsync_end = 280 + 48 + 4, + .vtotal = 280 + 48 + 4 + 4, + .width_mm = 37, + .height_mm = 43, .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, }; @@ -643,7 +643,9 @@ if (ret) return dev_err_probe(dev, ret, "Failed to get backlight\n"); - of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation); + ret = of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation); + if (ret) + return dev_err_probe(&spi->dev, ret, "Failed to get orientation\n"); drm_panel_add(&ctx->panel); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panel/panel-visionox-rm69299.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panel/panel-visionox-rm69299.c @@ -253,8 +253,6 @@ struct visionox_rm69299 *ctx = mipi_dsi_get_drvdata(dsi); mipi_dsi_detach(ctx->dsi); - mipi_dsi_device_unregister(ctx->dsi); - drm_panel_remove(&ctx->panel); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -441,19 +441,19 @@ gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present); ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO, - val, !val, 1, 1000); + val, !val, 1, 2000); if (ret) dev_err(pfdev->dev, "shader power transition timeout"); gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO, - val, !val, 1, 1000); + val, !val, 1, 2000); if (ret) dev_err(pfdev->dev, "tiler power transition timeout"); gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present); ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO, - val, !val, 0, 1000); + val, !val, 0, 2000); if (ret) dev_err(pfdev->dev, "l2 power transition timeout"); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -502,11 +502,18 @@ mapping_set_unevictable(mapping); for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) { + /* Can happen if the last fault only partially filled this + * section of the pages array before failing. In that case + * we skip already filled pages. + */ + if (pages[i]) + continue; + pages[i] = shmem_read_mapping_page(mapping, i); if (IS_ERR(pages[i])) { ret = PTR_ERR(pages[i]); pages[i] = NULL; - goto err_pages; + goto err_unlock; } } @@ -514,7 +521,7 @@ ret = sg_alloc_table_from_pages(sgt, pages + page_offset, NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL); if (ret) - goto err_pages; + goto err_unlock; ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0); if (ret) @@ -537,8 +544,6 @@ err_map: sg_free_table(sgt); -err_pages: - drm_gem_shmem_put_pages(&bo->base); err_unlock: dma_resv_unlock(obj->resv); err_bo: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/ni.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/ni.c @@ -813,7 +813,7 @@ err = 0; } else if (rdev->smc_fw->size != smc_req_size) { pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n", - rdev->mc_fw->size, fw_name); + rdev->smc_fw->size, fw_name); err = -EINVAL; } } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/pptable.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/pptable.h @@ -424,7 +424,7 @@ typedef struct _ATOM_PPLIB_STATE_V2 { //number of valid dpm levels in this state; Driver uses it to calculate the whole - //size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR) + //size of the state: struct_size(ATOM_PPLIB_STATE_V2, clockInfoIndex, ucNumDPMLevels) UCHAR ucNumDPMLevels; //a index to the array of nonClockInfos @@ -432,14 +432,14 @@ /** * Driver will read the first ucNumDPMLevels in this array */ - UCHAR clockInfoIndex[1]; + UCHAR clockInfoIndex[] __counted_by(ucNumDPMLevels); } ATOM_PPLIB_STATE_V2; typedef struct _StateArray{ //how many states we have UCHAR ucNumEntries; - ATOM_PPLIB_STATE_V2 states[1]; + ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries); }StateArray; @@ -450,7 +450,7 @@ //sizeof(ATOM_PPLIB_CLOCK_INFO) UCHAR ucEntrySize; - UCHAR clockInfo[1]; + UCHAR clockInfo[] __counted_by(ucNumEntries); }ClockInfoArray; typedef struct _NonClockInfoArray{ @@ -460,7 +460,7 @@ //sizeof(ATOM_PPLIB_NONCLOCK_INFO) UCHAR ucEntrySize; - ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1]; + ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries); }NonClockInfoArray; typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/radeon.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/radeon.h @@ -132,7 +132,6 @@ /* RADEON_IB_POOL_SIZE must be a power of 2 */ #define RADEON_IB_POOL_SIZE 16 #define RADEON_DEBUGFS_MAX_COMPONENTS 32 -#define RADEONFB_CONN_LIMIT 4 #define RADEON_BIOS_NUM_SCRATCH 8 /* internal ring indices */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/radeon_atombios.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/radeon_atombios.c @@ -923,8 +923,12 @@ max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO; for (i = 0; i < max_device; i++) { - ATOM_CONNECTOR_INFO_I2C ci = - supported_devices->info.asConnInfo[i]; + ATOM_CONNECTOR_INFO_I2C ci; + + if (frev > 1) + ci = supported_devices->info_2d1.asConnInfo[i]; + else + ci = supported_devices->info.asConnInfo[i]; bios_connectors[i].valid = false; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/radeon_display.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/radeon_display.c @@ -683,7 +683,7 @@ struct radeon_device *rdev = dev->dev_private; struct radeon_crtc *radeon_crtc; - radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); + radeon_crtc = kzalloc(sizeof(*radeon_crtc), GFP_KERNEL); if (radeon_crtc == NULL) return; @@ -709,12 +709,6 @@ dev->mode_config.cursor_width = radeon_crtc->max_cursor_width; dev->mode_config.cursor_height = radeon_crtc->max_cursor_height; -#if 0 - radeon_crtc->mode_set.crtc = &radeon_crtc->base; - radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); - radeon_crtc->mode_set.num_connectors = 0; -#endif - if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom)) radeon_atombios_init_crtc(dev, radeon_crtc); else --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/radeon_gem.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/radeon_gem.c @@ -641,7 +641,7 @@ if (r) goto error_unlock; - if (bo_va->it.start) + if (bo_va->it.start && bo_va->bo) r = radeon_vm_bo_update(rdev, bo_va, bo_va->bo->tbo.resource); error_unlock: --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/radeon/sumo_dpm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1621,6 +1621,8 @@ for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { if (table[i].ulSupportedSCLK != 0) { + if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) + continue; vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = table[i].usVoltageID; vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/renesas/rcar-du/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/renesas/rcar-du/Kconfig @@ -25,8 +25,8 @@ config DRM_RCAR_DW_HDMI tristate "R-Car Gen3 and RZ/G2 DU HDMI Encoder Support" depends on DRM && OF + depends on DRM_DW_HDMI depends on DRM_RCAR_DU || COMPILE_TEST - select DRM_DW_HDMI help Enable support for R-Car Gen3 or RZ/G2 internal HDMI encoder. --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c @@ -171,6 +171,13 @@ drm_kms_helper_poll_fini(ddev); } +static void shmob_drm_shutdown(struct platform_device *pdev) +{ + struct shmob_drm_device *sdev = platform_get_drvdata(pdev); + + drm_atomic_helper_shutdown(&sdev->ddev); +} + static int shmob_drm_probe(struct platform_device *pdev) { struct shmob_drm_platform_data *pdata = pdev->dev.platform_data; @@ -273,6 +280,7 @@ static struct platform_driver shmob_drm_platform_driver = { .probe = shmob_drm_probe, .remove_new = shmob_drm_remove, + .shutdown = shmob_drm_shutdown, .driver = { .name = "shmob-drm", .of_match_table = of_match_ptr(shmob_drm_of_table), --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/rockchip/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/rockchip/Kconfig @@ -7,7 +7,6 @@ select DRM_PANEL select VIDEOMODE_HELPERS select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP - select DRM_DW_HDMI if ROCKCHIP_DW_HDMI select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI @@ -57,6 +56,7 @@ config ROCKCHIP_DW_HDMI bool "Rockchip specific extensions for Synopsys DW HDMI" + depends on DRM_DW_HDMI help This selects support for Rockchip SoC specific extensions for the Synopsys DesignWare HDMI driver. If you want to --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/rockchip/inno_hdmi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -411,7 +411,7 @@ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); - value = mode->hsync_start - mode->hdisplay; + value = mode->htotal - mode->hsync_start; hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); @@ -426,7 +426,7 @@ value = mode->vtotal - mode->vdisplay; hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); - value = mode->vsync_start - mode->vdisplay; + value = mode->vtotal - mode->vsync_start; hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); value = mode->vsync_end - mode->vsync_start; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -706,6 +706,8 @@ const struct drm_format_info *info; u16 hor_scl_mode, ver_scl_mode; u16 hscl_filter_mode, vscl_filter_mode; + uint16_t cbcr_src_w = src_w; + uint16_t cbcr_src_h = src_h; u8 gt2 = 0; u8 gt4 = 0; u32 val; @@ -763,27 +765,27 @@ vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode); if (info->is_yuv) { - src_w /= info->hsub; - src_h /= info->vsub; + cbcr_src_w /= info->hsub; + cbcr_src_h /= info->vsub; gt4 = 0; gt2 = 0; - if (src_h >= (4 * dst_h)) { + if (cbcr_src_h >= (4 * dst_h)) { gt4 = 1; - src_h >>= 2; - } else if (src_h >= (2 * dst_h)) { + cbcr_src_h >>= 2; + } else if (cbcr_src_h >= (2 * dst_h)) { gt2 = 1; - src_h >>= 1; + cbcr_src_h >>= 1; } - hor_scl_mode = scl_get_scl_mode(src_w, dst_w); - ver_scl_mode = scl_get_scl_mode(src_h, dst_h); + hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w); + ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h); - val = vop2_scale_factor(src_w, dst_w); + val = vop2_scale_factor(cbcr_src_w, dst_w); vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val); - val = vop2_scale_factor(src_h, dst_h); + val = vop2_scale_factor(cbcr_src_h, dst_h); vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val); vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -576,8 +576,7 @@ ret = -EINVAL; goto err_put_port; } else if (ret) { - DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n"); - ret = -EPROBE_DEFER; + dev_err_probe(dev, ret, "failed to find panel and bridge node\n"); goto err_put_port; } if (lvds->panel) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -17,9 +17,7 @@ static const uint32_t formats_cluster[] = { DRM_FORMAT_XRGB2101010, - DRM_FORMAT_ARGB2101010, DRM_FORMAT_XBGR2101010, - DRM_FORMAT_ABGR2101010, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/scheduler/sched_entity.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/scheduler/sched_entity.c @@ -71,13 +71,19 @@ entity->guilty = guilty; entity->num_sched_list = num_sched_list; entity->priority = priority; + /* + * It's perfectly valid to initialize an entity without having a valid + * scheduler attached. It's just not valid to use the scheduler before it + * is initialized itself. + */ entity->sched_list = num_sched_list > 1 ? sched_list : NULL; RCU_INIT_POINTER(entity->last_scheduled, NULL); RB_CLEAR_NODE(&entity->rb_tree_node); - if (!sched_list[0]->sched_rq) { - /* Warn drivers not to do this and to fix their DRM - * calling order. + if (num_sched_list && !sched_list[0]->sched_rq) { + /* Since every entry covered by num_sched_list + * should be non-NULL and therefore we warn drivers + * not to do this and to fix their DRM calling order. */ pr_warn("%s: called with uninitialized scheduler\n", __func__); } else if (num_sched_list) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/sun4i/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/sun4i/Kconfig @@ -57,8 +57,8 @@ config DRM_SUN8I_DW_HDMI tristate "Support for Allwinner version of DesignWare HDMI" depends on DRM_SUN4I + depends on DRM_DW_HDMI default DRM_SUN4I - select DRM_DW_HDMI help Choose this option if you have an Allwinner SoC with the DesignWare HDMI controller. SoCs that support HDMI and --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -82,7 +82,8 @@ return 0; } -static void sun4i_hdmi_disable(struct drm_encoder *encoder) +static void sun4i_hdmi_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); u32 val; @@ -96,37 +97,17 @@ clk_disable_unprepare(hdmi->tmds_clk); } -static void sun4i_hdmi_enable(struct drm_encoder *encoder) +static void sun4i_hdmi_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); struct drm_display_info *display = &hdmi->connector.display_info; + unsigned int x, y; u32 val = 0; DRM_DEBUG_DRIVER("Enabling the HDMI Output\n"); - clk_prepare_enable(hdmi->tmds_clk); - - sun4i_hdmi_setup_avi_infoframes(hdmi, mode); - val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); - val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); - writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0)); - - val = SUN4I_HDMI_VID_CTRL_ENABLE; - if (display->is_hdmi) - val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; - - writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); -} - -static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder); - unsigned int x, y; - u32 val; - clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000); clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000); @@ -178,6 +159,19 @@ val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC; writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG); + + clk_prepare_enable(hdmi->tmds_clk); + + sun4i_hdmi_setup_avi_infoframes(hdmi, mode); + val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI); + val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END); + writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0)); + + val = SUN4I_HDMI_VID_CTRL_ENABLE; + if (display->is_hdmi) + val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; + + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); } static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder, @@ -201,9 +195,8 @@ static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = { .atomic_check = sun4i_hdmi_atomic_check, - .disable = sun4i_hdmi_disable, - .enable = sun4i_hdmi_enable, - .mode_set = sun4i_hdmi_mode_set, + .atomic_disable = sun4i_hdmi_disable, + .atomic_enable = sun4i_hdmi_enable, .mode_valid = sun4i_hdmi_mode_valid, }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tegra/dpaux.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tegra/dpaux.c @@ -522,7 +522,7 @@ if (err < 0) { dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n", dpaux->irq, err); - return err; + goto err_pm_disable; } disable_irq(dpaux->irq); @@ -542,7 +542,7 @@ */ err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C); if (err < 0) - return err; + goto err_pm_disable; #ifdef CONFIG_GENERIC_PINCONF dpaux->desc.name = dev_name(&pdev->dev); @@ -555,7 +555,8 @@ dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux); if (IS_ERR(dpaux->pinctrl)) { dev_err(&pdev->dev, "failed to register pincontrol\n"); - return PTR_ERR(dpaux->pinctrl); + err = PTR_ERR(dpaux->pinctrl); + goto err_pm_disable; } #endif /* enable and clear all interrupts */ @@ -571,10 +572,15 @@ err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux); if (err < 0) { dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err); - return err; + goto err_pm_disable; } return 0; + +err_pm_disable: + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return err; } static void tegra_dpaux_remove(struct platform_device *pdev) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tegra/dsi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tegra/dsi.c @@ -1544,9 +1544,11 @@ np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0); if (np) { struct platform_device *gangster = of_find_device_by_node(np); + of_node_put(np); + if (!gangster) + return -EPROBE_DEFER; dsi->slave = platform_get_drvdata(gangster); - of_node_put(np); if (!dsi->slave) { put_device(&gangster->dev); @@ -1594,44 +1596,58 @@ if (!pdev->dev.pm_domain) { dsi->rst = devm_reset_control_get(&pdev->dev, "dsi"); - if (IS_ERR(dsi->rst)) - return PTR_ERR(dsi->rst); + if (IS_ERR(dsi->rst)) { + err = PTR_ERR(dsi->rst); + goto remove; + } } dsi->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(dsi->clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk), - "cannot get DSI clock\n"); + if (IS_ERR(dsi->clk)) { + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk), + "cannot get DSI clock\n"); + goto remove; + } dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); - if (IS_ERR(dsi->clk_lp)) - return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp), - "cannot get low-power clock\n"); + if (IS_ERR(dsi->clk_lp)) { + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp), + "cannot get low-power clock\n"); + goto remove; + } dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); - if (IS_ERR(dsi->clk_parent)) - return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent), - "cannot get parent clock\n"); + if (IS_ERR(dsi->clk_parent)) { + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent), + "cannot get parent clock\n"); + goto remove; + } dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); - if (IS_ERR(dsi->vdd)) - return dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd), - "cannot get VDD supply\n"); + if (IS_ERR(dsi->vdd)) { + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd), + "cannot get VDD supply\n"); + goto remove; + } err = tegra_dsi_setup_clocks(dsi); if (err < 0) { dev_err(&pdev->dev, "cannot setup clocks\n"); - return err; + goto remove; } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); dsi->regs = devm_ioremap_resource(&pdev->dev, regs); - if (IS_ERR(dsi->regs)) - return PTR_ERR(dsi->regs); + if (IS_ERR(dsi->regs)) { + err = PTR_ERR(dsi->regs); + goto remove; + } dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node); - if (IS_ERR(dsi->mipi)) - return PTR_ERR(dsi->mipi); + if (IS_ERR(dsi->mipi)) { + err = PTR_ERR(dsi->mipi); + goto remove; + } dsi->host.ops = &tegra_dsi_host_ops; dsi->host.dev = &pdev->dev; @@ -1659,9 +1675,12 @@ return 0; unregister: + pm_runtime_disable(&pdev->dev); mipi_dsi_host_unregister(&dsi->host); mipi_free: tegra_mipi_free(dsi->mipi); +remove: + tegra_output_remove(&dsi->output); return err; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tegra/fb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tegra/fb.c @@ -159,6 +159,7 @@ if (gem->size < size) { err = -EINVAL; + drm_gem_object_put(gem); goto unreference; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tegra/hdmi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tegra/hdmi.c @@ -1856,12 +1856,14 @@ return err; hdmi->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(hdmi->regs)) - return PTR_ERR(hdmi->regs); + if (IS_ERR(hdmi->regs)) { + err = PTR_ERR(hdmi->regs); + goto remove; + } err = platform_get_irq(pdev, 0); if (err < 0) - return err; + goto remove; hdmi->irq = err; @@ -1870,18 +1872,18 @@ if (err < 0) { dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", hdmi->irq, err); - return err; + goto remove; } platform_set_drvdata(pdev, hdmi); err = devm_pm_runtime_enable(&pdev->dev); if (err) - return err; + goto remove; err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); if (err) - return err; + goto remove; INIT_LIST_HEAD(&hdmi->client.list); hdmi->client.ops = &hdmi_client_ops; @@ -1891,10 +1893,14 @@ if (err < 0) { dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); - return err; + goto remove; } return 0; + +remove: + tegra_output_remove(&hdmi->output); + return err; } static void tegra_hdmi_remove(struct platform_device *pdev) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tegra/output.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tegra/output.c @@ -142,8 +142,10 @@ GPIOD_IN, "HDMI hotplug detect"); if (IS_ERR(output->hpd_gpio)) { - if (PTR_ERR(output->hpd_gpio) != -ENOENT) - return PTR_ERR(output->hpd_gpio); + if (PTR_ERR(output->hpd_gpio) != -ENOENT) { + err = PTR_ERR(output->hpd_gpio); + goto put_i2c; + } output->hpd_gpio = NULL; } @@ -152,7 +154,7 @@ err = gpiod_to_irq(output->hpd_gpio); if (err < 0) { dev_err(output->dev, "gpiod_to_irq(): %d\n", err); - return err; + goto put_i2c; } output->hpd_irq = err; @@ -165,7 +167,7 @@ if (err < 0) { dev_err(output->dev, "failed to request IRQ#%u: %d\n", output->hpd_irq, err); - return err; + goto put_i2c; } output->connector.polled = DRM_CONNECTOR_POLL_HPD; @@ -179,6 +181,12 @@ } return 0; + +put_i2c: + if (output->ddc) + i2c_put_adapter(output->ddc); + + return err; } void tegra_output_remove(struct tegra_output *output) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tegra/rgb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tegra/rgb.c @@ -225,26 +225,28 @@ rgb->clk = devm_clk_get(dc->dev, NULL); if (IS_ERR(rgb->clk)) { dev_err(dc->dev, "failed to get clock\n"); - return PTR_ERR(rgb->clk); + err = PTR_ERR(rgb->clk); + goto remove; } rgb->clk_parent = devm_clk_get(dc->dev, "parent"); if (IS_ERR(rgb->clk_parent)) { dev_err(dc->dev, "failed to get parent clock\n"); - return PTR_ERR(rgb->clk_parent); + err = PTR_ERR(rgb->clk_parent); + goto remove; } err = clk_set_parent(rgb->clk, rgb->clk_parent); if (err < 0) { dev_err(dc->dev, "failed to set parent clock: %d\n", err); - return err; + goto remove; } rgb->pll_d_out0 = clk_get_sys(NULL, "pll_d_out0"); if (IS_ERR(rgb->pll_d_out0)) { err = PTR_ERR(rgb->pll_d_out0); dev_err(dc->dev, "failed to get pll_d_out0: %d\n", err); - return err; + goto remove; } if (dc->soc->has_pll_d2_out0) { @@ -252,13 +254,19 @@ if (IS_ERR(rgb->pll_d2_out0)) { err = PTR_ERR(rgb->pll_d2_out0); dev_err(dc->dev, "failed to get pll_d2_out0: %d\n", err); - return err; + goto put_pll; } } dc->rgb = &rgb->output; return 0; + +put_pll: + clk_put(rgb->pll_d_out0); +remove: + tegra_output_remove(&rgb->output); + return err; } void tegra_dc_rgb_remove(struct tegra_dc *dc) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tests/drm_buddy_test.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tests/drm_buddy_test.c @@ -260,30 +260,30 @@ KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, ps, ps, list, 0), - "buddy_alloc hit an error size=%u\n", + "buddy_alloc hit an error size=%lu\n", ps); } while (++i < n_pages); KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, 3 * ps, ps, &allocated, DRM_BUDDY_CONTIGUOUS_ALLOCATION), - "buddy_alloc didn't error size=%u\n", 3 * ps); + "buddy_alloc didn't error size=%lu\n", 3 * ps); drm_buddy_free_list(&mm, &middle); KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, 3 * ps, ps, &allocated, DRM_BUDDY_CONTIGUOUS_ALLOCATION), - "buddy_alloc didn't error size=%u\n", 3 * ps); + "buddy_alloc didn't error size=%lu\n", 3 * ps); KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, 2 * ps, ps, &allocated, DRM_BUDDY_CONTIGUOUS_ALLOCATION), - "buddy_alloc didn't error size=%u\n", 2 * ps); + "buddy_alloc didn't error size=%lu\n", 2 * ps); drm_buddy_free_list(&mm, &right); KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, 3 * ps, ps, &allocated, DRM_BUDDY_CONTIGUOUS_ALLOCATION), - "buddy_alloc didn't error size=%u\n", 3 * ps); + "buddy_alloc didn't error size=%lu\n", 3 * ps); /* * At this point we should have enough contiguous space for 2 blocks, * however they are never buddies (since we freed middle and right) so @@ -292,13 +292,13 @@ KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, 2 * ps, ps, &allocated, DRM_BUDDY_CONTIGUOUS_ALLOCATION), - "buddy_alloc hit an error size=%u\n", 2 * ps); + "buddy_alloc hit an error size=%lu\n", 2 * ps); drm_buddy_free_list(&mm, &left); KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, 3 * ps, ps, &allocated, DRM_BUDDY_CONTIGUOUS_ALLOCATION), - "buddy_alloc hit an error size=%u\n", 3 * ps); + "buddy_alloc hit an error size=%lu\n", 3 * ps); total = 0; list_for_each_entry(block, &allocated, link) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tests/drm_mm_test.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tests/drm_mm_test.c @@ -157,7 +157,7 @@ /* After creation, it should all be one massive hole */ if (!assert_one_hole(test, &mm, 0, size)) { - KUNIT_FAIL(test, ""); + KUNIT_FAIL(test, "mm not one hole on creation"); goto out; } @@ -171,14 +171,14 @@ /* After filling the range entirely, there should be no holes */ if (!assert_no_holes(test, &mm)) { - KUNIT_FAIL(test, ""); + KUNIT_FAIL(test, "mm has holes when filled"); goto out; } /* And then after emptying it again, the massive hole should be back */ drm_mm_remove_node(&tmp); if (!assert_one_hole(test, &mm, 0, size)) { - KUNIT_FAIL(test, ""); + KUNIT_FAIL(test, "mm does not have single hole after emptying"); goto out; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tidss/tidss_crtc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tidss/tidss_crtc.c @@ -265,6 +265,16 @@ reinit_completion(&tcrtc->framedone_completion); + /* + * If a layer is left enabled when the videoport is disabled, and the + * vid pipeline that was used for the layer is taken into use on + * another videoport, the DSS will report sync lost issues. Disable all + * the layers here as a work-around. + */ + for (u32 layer = 0; layer < tidss->feat->num_planes; layer++) + dispc_ovr_enable_layer(tidss->dispc, tcrtc->hw_videoport, layer, + false); + dispc_vp_disable(tidss->dispc, tcrtc->hw_videoport); if (!wait_for_completion_timeout(&tcrtc->framedone_completion, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/tidss/tidss_plane.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/tidss/tidss_plane.c @@ -213,7 +213,7 @@ drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs); - drm_plane_create_zpos_property(&tplane->plane, hw_plane_id, 0, + drm_plane_create_zpos_property(&tplane->plane, tidss->num_planes, 0, num_planes - 1); ret = drm_plane_create_color_properties(&tplane->plane, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ttm/ttm_bo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/ttm/ttm_bo.c @@ -346,6 +346,7 @@ if (!dma_resv_test_signaled(bo->base.resv, DMA_RESV_USAGE_BOOKKEEP) || (want_init_on_free() && (bo->ttm != NULL)) || + bo->type == ttm_bo_type_sg || !dma_resv_trylock(bo->base.resv)) { /* The BO is not idle, resurrect it for delayed destroy */ ttm_bo_flush_all_fences(bo); @@ -770,7 +771,7 @@ * This function may sleep while waiting for space to become available. * Returns: * -EBUSY: No space available (only if no_wait == 1). - * -ENOMEM: Could not allocate memory for the buffer object, either due to + * -ENOSPC: Could not allocate space for the buffer object, either due to * fragmentation or concurrent allocators. * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. */ @@ -830,7 +831,7 @@ goto error; } - ret = -ENOMEM; + ret = -ENOSPC; if (!type_found) { pr_err(TTM_PFX "No compatible memory type found\n"); ret = -EINVAL; @@ -916,6 +917,9 @@ return -EINVAL; ret = ttm_bo_move_buffer(bo, placement, ctx); + /* For backward compatibility with userspace */ + if (ret == -ENOSPC) + return -ENOMEM; if (ret) return ret; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ttm/ttm_bo_util.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -294,7 +294,13 @@ enum ttm_caching caching; man = ttm_manager_type(bo->bdev, res->mem_type); - caching = man->use_tt ? bo->ttm->caching : res->bus.caching; + if (man->use_tt) { + caching = bo->ttm->caching; + if (bo->ttm->page_flags & TTM_TT_FLAG_DECRYPTED) + tmp = pgprot_decrypted(tmp); + } else { + caching = res->bus.caching; + } return ttm_prot_from_caching(caching, tmp); } @@ -337,6 +343,8 @@ .no_wait_gpu = false }; struct ttm_tt *ttm = bo->ttm; + struct ttm_resource_manager *man = + ttm_manager_type(bo->bdev, bo->resource->mem_type); pgprot_t prot; int ret; @@ -346,7 +354,8 @@ if (ret) return ret; - if (num_pages == 1 && ttm->caching == ttm_cached) { + if (num_pages == 1 && ttm->caching == ttm_cached && + !(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) { /* * We're mapping a single page, and the desired * page protection is consistent with the bo. --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ttm/ttm_pool.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/ttm/ttm_pool.c @@ -288,17 +288,23 @@ enum ttm_caching caching, unsigned int order) { - if (pool->use_dma_alloc || pool->nid != NUMA_NO_NODE) + if (pool->use_dma_alloc) return &pool->caching[caching].orders[order]; #ifdef CONFIG_X86 switch (caching) { case ttm_write_combined: + if (pool->nid != NUMA_NO_NODE) + return &pool->caching[caching].orders[order]; + if (pool->use_dma32) return &global_dma32_write_combined[order]; return &global_write_combined[order]; case ttm_uncached: + if (pool->nid != NUMA_NO_NODE) + return &pool->caching[caching].orders[order]; + if (pool->use_dma32) return &global_dma32_uncached[order]; @@ -566,11 +572,17 @@ pool->use_dma_alloc = use_dma_alloc; pool->use_dma32 = use_dma32; - if (use_dma_alloc || nid != NUMA_NO_NODE) { - for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) - for (j = 0; j < NR_PAGE_ORDERS; ++j) - ttm_pool_type_init(&pool->caching[i].orders[j], - pool, i, j); + for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) { + for (j = 0; j < NR_PAGE_ORDERS; ++j) { + struct ttm_pool_type *pt; + + /* Initialize only pool types which are actually used */ + pt = ttm_pool_select_type(pool, i, j); + if (pt != &pool->caching[i].orders[j]) + continue; + + ttm_pool_type_init(pt, pool, i, j); + } } } EXPORT_SYMBOL(ttm_pool_init); @@ -599,10 +611,16 @@ { unsigned int i, j; - if (pool->use_dma_alloc || pool->nid != NUMA_NO_NODE) { - for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) - for (j = 0; j < NR_PAGE_ORDERS; ++j) - ttm_pool_type_fini(&pool->caching[i].orders[j]); + for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) { + for (j = 0; j < NR_PAGE_ORDERS; ++j) { + struct ttm_pool_type *pt; + + pt = ttm_pool_select_type(pool, i, j); + if (pt != &pool->caching[i].orders[j]) + continue; + + ttm_pool_type_fini(pt); + } } /* We removed the pool types from the LRU, but we need to also make sure --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/ttm/ttm_tt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/ttm/ttm_tt.c @@ -31,11 +31,14 @@ #define pr_fmt(fmt) "[TTM] " fmt +#include #include #include #include #include #include +#include +#include #include #include @@ -60,6 +63,7 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc) { struct ttm_device *bdev = bo->bdev; + struct drm_device *ddev = bo->base.dev; uint32_t page_flags = 0; dma_resv_assert_held(bo->base.resv); @@ -81,6 +85,15 @@ pr_err("Illegal buffer object type\n"); return -EINVAL; } + /* + * When using dma_alloc_coherent with memory encryption the + * mapped TT pages need to be decrypted or otherwise the drivers + * will end up sending encrypted mem to the gpu. + */ + if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { + page_flags |= TTM_TT_FLAG_DECRYPTED; + drm_info_once(ddev, "TT memory decryption enabled."); + } bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags); if (unlikely(bo->ttm == NULL)) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/v3d/v3d_irq.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/v3d/v3d_irq.c @@ -105,7 +105,6 @@ struct v3d_file_priv *file = v3d->bin_job->base.file->driver_priv; u64 runtime = local_clock() - file->start_ns[V3D_BIN]; - file->enabled_ns[V3D_BIN] += local_clock() - file->start_ns[V3D_BIN]; file->jobs_sent[V3D_BIN]++; v3d->queue[V3D_BIN].jobs_sent++; @@ -126,7 +125,6 @@ struct v3d_file_priv *file = v3d->render_job->base.file->driver_priv; u64 runtime = local_clock() - file->start_ns[V3D_RENDER]; - file->enabled_ns[V3D_RENDER] += local_clock() - file->start_ns[V3D_RENDER]; file->jobs_sent[V3D_RENDER]++; v3d->queue[V3D_RENDER].jobs_sent++; @@ -147,7 +145,6 @@ struct v3d_file_priv *file = v3d->csd_job->base.file->driver_priv; u64 runtime = local_clock() - file->start_ns[V3D_CSD]; - file->enabled_ns[V3D_CSD] += local_clock() - file->start_ns[V3D_CSD]; file->jobs_sent[V3D_CSD]++; v3d->queue[V3D_CSD].jobs_sent++; @@ -195,7 +192,6 @@ struct v3d_file_priv *file = v3d->tfu_job->base.file->driver_priv; u64 runtime = local_clock() - file->start_ns[V3D_TFU]; - file->enabled_ns[V3D_TFU] += local_clock() - file->start_ns[V3D_TFU]; file->jobs_sent[V3D_TFU]++; v3d->queue[V3D_TFU].jobs_sent++; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vc4/vc4_hdmi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -508,7 +508,7 @@ edid = drm_get_edid(connector, vc4_hdmi->ddc); cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); if (!edid) - return -ENODEV; + return 0; drm_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); @@ -2739,6 +2739,8 @@ index = 1; addr = of_get_address(dev->of_node, index, NULL, NULL); + if (!addr) + return -EINVAL; vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset; vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vc4/vc4_plane.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vc4/vc4_plane.c @@ -1505,9 +1505,6 @@ drm_gem_plane_helper_prepare_fb(plane, state); - if (plane->state->fb == state->fb) - return 0; - return vc4_bo_inc_usecnt(bo); } @@ -1516,7 +1513,7 @@ { struct vc4_bo *bo; - if (plane->state->fb == state->fb || !state->fb) + if (!state->fb) return; bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vkms/vkms_composer.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vkms/vkms_composer.c @@ -123,6 +123,8 @@ enum lut_channel channel) { s64 lut_index = get_lut_index(lut, channel_value); + u16 *floor_lut_value, *ceil_lut_value; + u16 floor_channel_value, ceil_channel_value; /* * This checks if `struct drm_color_lut` has any gap added by the compiler @@ -130,11 +132,15 @@ */ static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4); - u16 *floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)]; - u16 *ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)]; + floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)]; + if (drm_fixp2int(lut_index) == (lut->lut_length - 1)) + /* We're at the end of the LUT array, use same value for ceil and floor */ + ceil_lut_value = floor_lut_value; + else + ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)]; - u16 floor_channel_value = floor_lut_value[channel]; - u16 ceil_channel_value = ceil_lut_value[channel]; + floor_channel_value = floor_lut_value[channel]; + ceil_channel_value = ceil_lut_value[channel]; return lerp_u16(floor_channel_value, ceil_channel_value, lut_index & DRM_FIXED_DECIMAL_MASK); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/Kconfig @@ -2,7 +2,7 @@ config DRM_VMWGFX tristate "DRM driver for VMware Virtual GPU" depends on DRM && PCI && MMU - depends on X86 || ARM64 + depends on (X86 && HYPERVISOR_GUEST) || ARM64 select DRM_TTM select DRM_TTM_HELPER select MAPPING_DIRTY_HELPERS --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c @@ -456,8 +456,10 @@ .no_wait_gpu = false }; u32 j, initial_line = dst_offset / dst_stride; - struct vmw_bo_blit_line_data d; + struct vmw_bo_blit_line_data d = {0}; int ret = 0; + struct page **dst_pages = NULL; + struct page **src_pages = NULL; /* Buffer objects need to be either pinned or reserved: */ if (!(dst->pin_count)) @@ -477,12 +479,35 @@ return ret; } + if (!src->ttm->pages && src->ttm->sg) { + src_pages = kvmalloc_array(src->ttm->num_pages, + sizeof(struct page *), GFP_KERNEL); + if (!src_pages) + return -ENOMEM; + ret = drm_prime_sg_to_page_array(src->ttm->sg, src_pages, + src->ttm->num_pages); + if (ret) + goto out; + } + if (!dst->ttm->pages && dst->ttm->sg) { + dst_pages = kvmalloc_array(dst->ttm->num_pages, + sizeof(struct page *), GFP_KERNEL); + if (!dst_pages) { + ret = -ENOMEM; + goto out; + } + ret = drm_prime_sg_to_page_array(dst->ttm->sg, dst_pages, + dst->ttm->num_pages); + if (ret) + goto out; + } + d.mapped_dst = 0; d.mapped_src = 0; d.dst_addr = NULL; d.src_addr = NULL; - d.dst_pages = dst->ttm->pages; - d.src_pages = src->ttm->pages; + d.dst_pages = dst->ttm->pages ? dst->ttm->pages : dst_pages; + d.src_pages = src->ttm->pages ? src->ttm->pages : src_pages; d.dst_num_pages = PFN_UP(dst->resource->size); d.src_num_pages = PFN_UP(src->resource->size); d.dst_prot = ttm_io_prot(dst, dst->resource, PAGE_KERNEL); @@ -504,6 +529,10 @@ kunmap_atomic(d.src_addr); if (d.dst_addr) kunmap_atomic(d.dst_addr); + if (src_pages) + kvfree(src_pages); + if (dst_pages) + kvfree(dst_pages); return ret; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -204,6 +204,7 @@ VMW_BO_DOMAIN_VRAM, VMW_BO_DOMAIN_VRAM); buf->places[0].lpfn = PFN_UP(bo->resource->size); + buf->busy_places[0].lpfn = PFN_UP(bo->resource->size); ret = ttm_bo_validate(bo, &buf->placement, &ctx); /* For some reason we didn't end up at the start of vram */ @@ -377,7 +378,8 @@ { struct ttm_operation_ctx ctx = { .interruptible = params->bo_type != ttm_bo_type_kernel, - .no_wait_gpu = false + .no_wait_gpu = false, + .resv = params->resv, }; struct ttm_device *bdev = &dev_priv->bdev; struct drm_device *vdev = &dev_priv->drm; @@ -394,8 +396,8 @@ vmw_bo_placement_set(vmw_bo, params->domain, params->busy_domain); ret = ttm_bo_init_reserved(bdev, &vmw_bo->tbo, params->bo_type, - &vmw_bo->placement, 0, &ctx, NULL, - NULL, destroy); + &vmw_bo->placement, 0, &ctx, + params->sg, params->resv, destroy); if (unlikely(ret)) return ret; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h @@ -55,6 +55,8 @@ enum ttm_bo_type bo_type; size_t size; bool pin; + struct dma_resv *resv; + struct sg_table *sg; }; /** --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -666,11 +666,12 @@ [vmw_dma_map_populate] = "Caching DMA mappings.", [vmw_dma_map_bind] = "Giving up DMA mappings early."}; - /* TTM currently doesn't fully support SEV encryption. */ - if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) - return -EINVAL; - - if (vmw_force_coherent) + /* + * When running with SEV we always want dma mappings, because + * otherwise ttm tt pool pages will bounce through swiotlb running + * out of available space. + */ + if (vmw_force_coherent || cc_platform_has(CC_ATTR_MEM_ENCRYPT)) dev_priv->map_mode = vmw_dma_alloc_coherent; else if (vmw_restrict_iommu) dev_priv->map_mode = vmw_dma_map_bind; @@ -955,13 +956,6 @@ vmw_read(dev_priv, SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); - /* - * Workaround for low memory 2D VMs to compensate for the - * allocation taken by fbdev - */ - if (!(dev_priv->capabilities & SVGA_CAP_3D)) - mem_size *= 3; - dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE; dev_priv->max_primary_mem = vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_MEM); @@ -1444,12 +1438,15 @@ root, "system_ttm"); ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, TTM_PL_VRAM), root, "vram_ttm"); - ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_GMR), - root, "gmr_ttm"); - ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_MOB), - root, "mob_ttm"); - ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_SYSTEM), - root, "system_mob_ttm"); + if (vmw->has_gmr) + ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_GMR), + root, "gmr_ttm"); + if (vmw->has_mob) { + ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_MOB), + root, "mob_ttm"); + ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_SYSTEM), + root, "system_mob_ttm"); + } } static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, @@ -1624,6 +1621,7 @@ .prime_fd_to_handle = vmw_prime_fd_to_handle, .prime_handle_to_fd = vmw_prime_handle_to_fd, + .gem_prime_import_sg_table = vmw_prime_import_sg_table, .fops = &vmwgfx_driver_fops, .name = VMWGFX_DRIVER_NAME, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1067,9 +1067,6 @@ int vmw_kms_write_svga(struct vmw_private *vmw_priv, unsigned width, unsigned height, unsigned pitch, unsigned bpp, unsigned depth); -bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, - uint32_t pitch, - uint32_t height); int vmw_kms_present(struct vmw_private *dev_priv, struct drm_file *file_priv, struct vmw_framebuffer *vfb, @@ -1131,6 +1128,9 @@ struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); +struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, + struct sg_table *table); /* * MemoryOBject management - vmwgfx_mob.c --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -447,7 +447,7 @@ vmw_res_type(ctx) == vmw_res_dx_context) { for (i = 0; i < cotable_max; ++i) { res = vmw_context_cotable(ctx, i); - if (IS_ERR(res)) + if (IS_ERR_OR_NULL(res)) continue; ret = vmw_execbuf_res_val_add(sw_context, res, @@ -1266,6 +1266,8 @@ return -EINVAL; cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY); + if (IS_ERR_OR_NULL(cotable_res)) + return cotable_res ? PTR_ERR(cotable_res) : -EINVAL; ret = vmw_cotable_notify(cotable_res, cmd->body.queryId); return ret; @@ -2484,6 +2486,8 @@ return ret; res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->defined_id); if (unlikely(ret != 0)) return ret; @@ -2569,8 +2573,8 @@ so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); - if (IS_ERR(res)) - return PTR_ERR(res); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; cmd = container_of(header, typeof(*cmd), header); ret = vmw_cotable_notify(res, cmd->defined_id); @@ -2689,6 +2693,8 @@ return -EINVAL; res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.shaderId); if (ret) return ret; @@ -3010,6 +3016,8 @@ } res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.soid); if (ret) return ret; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -991,7 +991,7 @@ } event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED; - event->event.base.length = sizeof(*event); + event->event.base.length = sizeof(event->event); event->event.user_data = user_data; ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c @@ -149,6 +149,38 @@ return ret; } +struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, + struct sg_table *table) +{ + int ret; + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_gem_object *gem = NULL; + struct vmw_bo *vbo; + struct vmw_bo_params params = { + .domain = (dev_priv->has_mob) ? VMW_BO_DOMAIN_SYS : VMW_BO_DOMAIN_VRAM, + .busy_domain = VMW_BO_DOMAIN_SYS, + .bo_type = ttm_bo_type_sg, + .size = attach->dmabuf->size, + .pin = false, + .resv = attach->dmabuf->resv, + .sg = table, + + }; + + dma_resv_lock(params.resv, NULL); + + ret = vmw_bo_create(dev_priv, ¶ms, &vbo); + if (ret != 0) + goto out_no_bo; + + vbo->tbo.base.funcs = &vmw_gem_object_funcs; + + gem = &vbo->tbo.base; +out_no_bo: + dma_resv_unlock(params.resv); + return gem; +} int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -64,8 +64,11 @@ ttm_resource_init(bo, place, *res); id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL); - if (id < 0) + if (id < 0) { + ttm_resource_fini(man, *res); + kfree(*res); return id; + } spin_lock(&gman->lock); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -35,6 +35,7 @@ #include #include #include +#include void vmw_du_cleanup(struct vmw_display_unit *du) { @@ -184,13 +185,12 @@ */ static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps) { - bool is_iomem; if (vps->surf) { if (vps->surf_mapped) return vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo); return vps->surf->snooper.image; } else if (vps->bo) - return ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem); + return vmw_bo_map_and_cache(vps->bo); return NULL; } @@ -216,7 +216,7 @@ new_image = vmw_du_cursor_plane_acquire_image(new_vps); changed = false; - if (old_image && new_image) + if (old_image && new_image && old_image != new_image) changed = memcmp(old_image, new_image, size) != 0; return changed; @@ -272,6 +272,7 @@ u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h); u32 i; u32 cursor_max_dim, mob_max_size; + struct vmw_fence_obj *fence = NULL; int ret; if (!dev_priv->has_mob || @@ -313,7 +314,15 @@ if (ret != 0) goto teardown; - vmw_bo_fence_single(&vps->cursor.bo->tbo, NULL); + ret = vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL); + if (ret != 0) { + ttm_bo_unreserve(&vps->cursor.bo->tbo); + goto teardown; + } + + dma_fence_wait(&fence->base, false); + dma_fence_put(&fence->base); + ttm_bo_unreserve(&vps->cursor.bo->tbo); return 0; @@ -643,22 +652,12 @@ { struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane); struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); - bool is_iomem; if (vps->surf_mapped) { vmw_bo_unmap(vps->surf->res.guest_memory_bo); vps->surf_mapped = false; } - if (vps->bo && ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem)) { - const int ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL); - - if (likely(ret == 0)) { - ttm_bo_kunmap(&vps->bo->map); - ttm_bo_unreserve(&vps->bo->tbo); - } - } - vmw_du_cursor_plane_unmap_cm(vps); vmw_du_put_cursor_mob(vcp, vps); @@ -694,6 +693,10 @@ int ret = 0; if (vps->surf) { + if (vps->surf_mapped) { + vmw_bo_unmap(vps->surf->res.guest_memory_bo); + vps->surf_mapped = false; + } vmw_surface_unreference(&vps->surf); vps->surf = NULL; } @@ -930,6 +933,7 @@ int vmw_du_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct vmw_private *vmw = vmw_priv(crtc->dev); struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, crtc); struct vmw_display_unit *du = vmw_crtc_to_du(new_state->crtc); @@ -937,9 +941,13 @@ bool has_primary = new_state->plane_mask & drm_plane_mask(crtc->primary); - /* We always want to have an active plane with an active CRTC */ - if (has_primary != new_state->enable) - return -EINVAL; + /* + * This is fine in general, but broken userspace might expect + * some actual rendering so give a clue as why it's blank. + */ + if (new_state->enable && !has_primary) + drm_dbg_driver(&vmw->drm, + "CRTC without a primary plane will be blank.\n"); if (new_state->connector_mask != connector_mask && @@ -2149,13 +2157,12 @@ return 0; } +static bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv, - uint32_t pitch, - uint32_t height) + u64 pitch, + u64 height) { - return ((u64) pitch * (u64) height) < (u64) - ((dev_priv->active_display_unit == vmw_du_screen_target) ? - dev_priv->max_primary_mem : dev_priv->vram_size); + return (pitch * height) < (u64)dev_priv->vram_size; } /** @@ -2278,107 +2285,6 @@ connector_status_connected : connector_status_disconnected); } -static struct drm_display_mode vmw_kms_connector_builtin[] = { - /* 640x480@60Hz */ - { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, - 752, 800, 0, 480, 489, 492, 525, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 800x600@60Hz */ - { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, - 968, 1056, 0, 600, 601, 605, 628, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1024x768@60Hz */ - { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1152x864@75Hz */ - { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, - 1344, 1600, 0, 864, 865, 868, 900, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x720@60Hz */ - { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74500, 1280, 1344, - 1472, 1664, 0, 720, 723, 728, 748, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x768@60Hz */ - { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, - 1472, 1664, 0, 768, 771, 778, 798, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x800@60Hz */ - { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, - 1480, 1680, 0, 800, 803, 809, 831, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 1280x960@60Hz */ - { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, - 1488, 1800, 0, 960, 961, 964, 1000, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1280x1024@60Hz */ - { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, - 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1360x768@60Hz */ - { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, - 1536, 1792, 0, 768, 771, 777, 795, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x1050@60Hz */ - { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, - 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1440x900@60Hz */ - { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, - 1672, 1904, 0, 900, 903, 909, 934, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1600x1200@60Hz */ - { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, - 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1680x1050@60Hz */ - { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, - 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1792x1344@60Hz */ - { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, - 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1853x1392@60Hz */ - { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, - 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1080@60Hz */ - { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 173000, 1920, 2048, - 2248, 2576, 0, 1080, 1083, 1088, 1120, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1200@60Hz */ - { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, - 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 1920x1440@60Hz */ - { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, - 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2560x1440@60Hz */ - { DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 241500, 2560, 2608, - 2640, 2720, 0, 1440, 1443, 1448, 1481, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 2560x1600@60Hz */ - { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, - 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, - /* 2880x1800@60Hz */ - { DRM_MODE("2880x1800", DRM_MODE_TYPE_DRIVER, 337500, 2880, 2928, - 2960, 3040, 0, 1800, 1803, 1809, 1852, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 3840x2160@60Hz */ - { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 533000, 3840, 3888, - 3920, 4000, 0, 2160, 2163, 2168, 2222, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* 3840x2400@60Hz */ - { DRM_MODE("3840x2400", DRM_MODE_TYPE_DRIVER, 592250, 3840, 3888, - 3920, 4000, 0, 2400, 2403, 2409, 2469, 0, - DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, - /* Terminate */ - { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, -}; - /** * vmw_guess_mode_timing - Provide fake timings for a * 60Hz vrefresh mode. @@ -2400,88 +2306,6 @@ } -int vmw_du_connector_fill_modes(struct drm_connector *connector, - uint32_t max_width, uint32_t max_height) -{ - struct vmw_display_unit *du = vmw_connector_to_du(connector); - struct drm_device *dev = connector->dev; - struct vmw_private *dev_priv = vmw_priv(dev); - struct drm_display_mode *mode = NULL; - struct drm_display_mode *bmode; - struct drm_display_mode prefmode = { DRM_MODE("preferred", - DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) - }; - int i; - u32 assumed_bpp = 4; - - if (dev_priv->assume_16bpp) - assumed_bpp = 2; - - max_width = min(max_width, dev_priv->texture_max_width); - max_height = min(max_height, dev_priv->texture_max_height); - - /* - * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/ - * HEIGHT registers. - */ - if (dev_priv->active_display_unit == vmw_du_screen_target) { - max_width = min(max_width, dev_priv->stdu_max_width); - max_height = min(max_height, dev_priv->stdu_max_height); - } - - /* Add preferred mode */ - mode = drm_mode_duplicate(dev, &prefmode); - if (!mode) - return 0; - mode->hdisplay = du->pref_width; - mode->vdisplay = du->pref_height; - vmw_guess_mode_timing(mode); - drm_mode_set_name(mode); - - if (vmw_kms_validate_mode_vram(dev_priv, - mode->hdisplay * assumed_bpp, - mode->vdisplay)) { - drm_mode_probed_add(connector, mode); - } else { - drm_mode_destroy(dev, mode); - mode = NULL; - } - - if (du->pref_mode) { - list_del_init(&du->pref_mode->head); - drm_mode_destroy(dev, du->pref_mode); - } - - /* mode might be null here, this is intended */ - du->pref_mode = mode; - - for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) { - bmode = &vmw_kms_connector_builtin[i]; - if (bmode->hdisplay > max_width || - bmode->vdisplay > max_height) - continue; - - if (!vmw_kms_validate_mode_vram(dev_priv, - bmode->hdisplay * assumed_bpp, - bmode->vdisplay)) - continue; - - mode = drm_mode_duplicate(dev, bmode); - if (!mode) - return 0; - - drm_mode_probed_add(connector, mode); - } - - drm_connector_list_update(connector); - /* Move the prefered mode first, help apps pick the right mode. */ - drm_mode_sort(&connector->modes); - - return 1; -} - /** * vmw_kms_update_layout_ioctl - Handler for DRM_VMW_UPDATE_LAYOUT ioctl * @dev: drm device for the ioctl @@ -3022,3 +2846,84 @@ vmw_validation_unref_lists(&val_ctx); return ret; } + +/** + * vmw_connector_mode_valid - implements drm_connector_helper_funcs.mode_valid callback + * + * @connector: the drm connector, part of a DU container + * @mode: drm mode to check + * + * Returns MODE_OK on success, or a drm_mode_status error code. + */ +enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + enum drm_mode_status ret; + struct drm_device *dev = connector->dev; + struct vmw_private *dev_priv = vmw_priv(dev); + u32 assumed_cpp = 4; + + if (dev_priv->assume_16bpp) + assumed_cpp = 2; + + ret = drm_mode_validate_size(mode, dev_priv->texture_max_width, + dev_priv->texture_max_height); + if (ret != MODE_OK) + return ret; + + if (!vmw_kms_validate_mode_vram(dev_priv, + mode->hdisplay * assumed_cpp, + mode->vdisplay)) + return MODE_MEM; + + return MODE_OK; +} + +/** + * vmw_connector_get_modes - implements drm_connector_helper_funcs.get_modes callback + * + * @connector: the drm connector, part of a DU container + * + * Returns the number of added modes. + */ +int vmw_connector_get_modes(struct drm_connector *connector) +{ + struct vmw_display_unit *du = vmw_connector_to_du(connector); + struct drm_device *dev = connector->dev; + struct vmw_private *dev_priv = vmw_priv(dev); + struct drm_display_mode *mode = NULL; + struct drm_display_mode prefmode = { DRM_MODE("preferred", + DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) + }; + u32 max_width; + u32 max_height; + u32 num_modes; + + /* Add preferred mode */ + mode = drm_mode_duplicate(dev, &prefmode); + if (!mode) + return 0; + + mode->hdisplay = du->pref_width; + mode->vdisplay = du->pref_height; + vmw_guess_mode_timing(mode); + drm_mode_set_name(mode); + + drm_mode_probed_add(connector, mode); + drm_dbg_kms(dev, "preferred mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); + + /* Probe connector for all modes not exceeding our geom limits */ + max_width = dev_priv->texture_max_width; + max_height = dev_priv->texture_max_height; + + if (dev_priv->active_display_unit == vmw_du_screen_target) { + max_width = min(dev_priv->stdu_max_width, max_width); + max_height = min(dev_priv->stdu_max_height, max_height); + } + + num_modes = 1 + drm_add_modes_noedid(connector, max_width, max_height); + + return num_modes; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -243,10 +243,10 @@ static const uint32_t __maybe_unused vmw_primary_plane_formats[] = { - DRM_FORMAT_XRGB1555, - DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB1555, }; static const uint32_t __maybe_unused vmw_cursor_plane_formats[] = { @@ -378,7 +378,6 @@ unsigned pref_width; unsigned pref_height; bool pref_active; - struct drm_display_mode *pref_mode; /* * Gui positioning @@ -428,8 +427,6 @@ void vmw_du_connector_restore(struct drm_connector *connector); enum drm_connector_status vmw_du_connector_detect(struct drm_connector *connector, bool force); -int vmw_du_connector_fill_modes(struct drm_connector *connector, - uint32_t max_width, uint32_t max_height); int vmw_kms_helper_dirty(struct vmw_private *dev_priv, struct vmw_framebuffer *framebuffer, const struct drm_clip_rect *clips, @@ -438,6 +435,9 @@ int num_clips, int increment, struct vmw_kms_dirty *dirty); +enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode); +int vmw_connector_get_modes(struct drm_connector *connector); void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv, struct drm_file *file_priv, --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -304,7 +304,7 @@ static const struct drm_connector_funcs vmw_legacy_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, - .fill_modes = vmw_du_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vmw_ldu_connector_destroy, .reset = vmw_du_connector_reset, .atomic_duplicate_state = vmw_du_connector_duplicate_state, @@ -313,6 +313,8 @@ static const struct drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = { + .get_modes = vmw_connector_get_modes, + .mode_valid = vmw_connector_mode_valid }; static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, @@ -449,7 +451,6 @@ ldu->base.pref_active = (unit == 0); ldu->base.pref_width = dev_priv->initial_width; ldu->base.pref_height = dev_priv->initial_height; - ldu->base.pref_mode = NULL; /* * Remove this after enabling atomic because property values can --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c @@ -75,8 +75,12 @@ int fd, u32 *handle) { struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; + int ret = ttm_prime_fd_to_handle(tfile, fd, handle); - return ttm_prime_fd_to_handle(tfile, fd, handle); + if (ret) + ret = drm_gem_prime_fd_to_handle(dev, file_priv, fd, handle); + + return ret; } int vmw_prime_handle_to_fd(struct drm_device *dev, @@ -85,5 +89,12 @@ int *prime_fd) { struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; - return ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd); + int ret; + + if (handle > VMWGFX_NUM_MOB) + ret = ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd); + else + ret = drm_gem_prime_handle_to_fd(dev, file_priv, handle, flags, prime_fd); + + return ret; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -347,7 +347,7 @@ static const struct drm_connector_funcs vmw_sou_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, - .fill_modes = vmw_du_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vmw_sou_connector_destroy, .reset = vmw_du_connector_reset, .atomic_duplicate_state = vmw_du_connector_duplicate_state, @@ -357,6 +357,8 @@ static const struct drm_connector_helper_funcs vmw_sou_connector_helper_funcs = { + .get_modes = vmw_connector_get_modes, + .mode_valid = vmw_connector_mode_valid }; @@ -826,7 +828,6 @@ sou->base.pref_active = (unit == 0); sou->base.pref_width = dev_priv->initial_width; sou->base.pref_height = dev_priv->initial_height; - sou->base.pref_mode = NULL; /* * Remove this after enabling atomic because property values can --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -41,7 +41,14 @@ #define vmw_connector_to_stdu(x) \ container_of(x, struct vmw_screen_target_display_unit, base.connector) - +/* + * Some renderers such as llvmpipe will align the width and height of their + * buffers to match their tile size. We need to keep this in mind when exposing + * modes to userspace so that this possible over-allocation will not exceed + * graphics memory. 64x64 pixels seems to be a reasonable upper bound for the + * tile size of current renderers. + */ +#define GPU_TILE_SIZE 64 enum stdu_content_type { SAME_AS_DISPLAY = 0, @@ -825,12 +832,46 @@ vmw_stdu_destroy(vmw_connector_to_stdu(connector)); } +static enum drm_mode_status +vmw_stdu_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + enum drm_mode_status ret; + struct drm_device *dev = connector->dev; + struct vmw_private *dev_priv = vmw_priv(dev); + u64 assumed_cpp = dev_priv->assume_16bpp ? 2 : 4; + /* Align width and height to account for GPU tile over-alignment */ + u64 required_mem = ALIGN(mode->hdisplay, GPU_TILE_SIZE) * + ALIGN(mode->vdisplay, GPU_TILE_SIZE) * + assumed_cpp; + required_mem = ALIGN(required_mem, PAGE_SIZE); + + ret = drm_mode_validate_size(mode, dev_priv->stdu_max_width, + dev_priv->stdu_max_height); + if (ret != MODE_OK) + return ret; + + ret = drm_mode_validate_size(mode, dev_priv->texture_max_width, + dev_priv->texture_max_height); + if (ret != MODE_OK) + return ret; + + if (required_mem > dev_priv->max_primary_mem) + return MODE_MEM; + + if (required_mem > dev_priv->max_mob_pages * PAGE_SIZE) + return MODE_MEM; + if (required_mem > dev_priv->max_mob_size) + return MODE_MEM; + + return MODE_OK; +} static const struct drm_connector_funcs vmw_stdu_connector_funcs = { .dpms = vmw_du_connector_dpms, .detect = vmw_du_connector_detect, - .fill_modes = vmw_du_connector_fill_modes, + .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vmw_stdu_connector_destroy, .reset = vmw_du_connector_reset, .atomic_duplicate_state = vmw_du_connector_duplicate_state, @@ -840,6 +881,8 @@ static const struct drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { + .get_modes = vmw_connector_get_modes, + .mode_valid = vmw_stdu_connector_mode_valid }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -220,13 +220,18 @@ switch (dev_priv->map_mode) { case vmw_dma_map_bind: case vmw_dma_map_populate: - vsgt->sgt = &vmw_tt->sgt; - ret = sg_alloc_table_from_pages_segment( - &vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0, - (unsigned long)vsgt->num_pages << PAGE_SHIFT, - dma_get_max_seg_size(dev_priv->drm.dev), GFP_KERNEL); - if (ret) - goto out_sg_alloc_fail; + if (vmw_tt->dma_ttm.page_flags & TTM_TT_FLAG_EXTERNAL) { + vsgt->sgt = vmw_tt->dma_ttm.sg; + } else { + vsgt->sgt = &vmw_tt->sgt; + ret = sg_alloc_table_from_pages_segment(&vmw_tt->sgt, + vsgt->pages, vsgt->num_pages, 0, + (unsigned long)vsgt->num_pages << PAGE_SHIFT, + dma_get_max_seg_size(dev_priv->drm.dev), + GFP_KERNEL); + if (ret) + goto out_sg_alloc_fail; + } ret = vmw_ttm_map_for_dma(vmw_tt); if (unlikely(ret != 0)) @@ -241,8 +246,9 @@ return 0; out_map_fail: - sg_free_table(vmw_tt->vsgt.sgt); - vmw_tt->vsgt.sgt = NULL; + drm_warn(&dev_priv->drm, "VSG table map failed!"); + sg_free_table(vsgt->sgt); + vsgt->sgt = NULL; out_sg_alloc_fail: return ret; } @@ -388,15 +394,17 @@ static int vmw_ttm_populate(struct ttm_device *bdev, struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) { - int ret; + bool external = (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0; - /* TODO: maybe completely drop this ? */ if (ttm_tt_is_populated(ttm)) return 0; - ret = ttm_pool_alloc(&bdev->pool, ttm, ctx); + if (external && ttm->sg) + return drm_prime_sg_to_dma_addr_array(ttm->sg, + ttm->dma_address, + ttm->num_pages); - return ret; + return ttm_pool_alloc(&bdev->pool, ttm, ctx); } static void vmw_ttm_unpopulate(struct ttm_device *bdev, @@ -404,6 +412,10 @@ { struct vmw_ttm_tt *vmw_tt = container_of(ttm, struct vmw_ttm_tt, dma_ttm); + bool external = (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0; + + if (external) + return; vmw_ttm_unbind(bdev, ttm); @@ -422,6 +434,7 @@ { struct vmw_ttm_tt *vmw_be; int ret; + bool external = bo->type == ttm_bo_type_sg; vmw_be = kzalloc(sizeof(*vmw_be), GFP_KERNEL); if (!vmw_be) @@ -430,7 +443,10 @@ vmw_be->dev_priv = vmw_priv_from_ttm(bo->bdev); vmw_be->mob = NULL; - if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent) + if (external) + page_flags |= TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE; + + if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent || external) ret = ttm_sg_tt_init(&vmw_be->dma_ttm, bo, page_flags, ttm_cached); else --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/Makefile @@ -42,7 +42,8 @@ quiet_cmd_wa_oob = GEN $(notdir $(generated_oob)) cmd_wa_oob = mkdir -p $(@D); $^ $(generated_oob) -$(generated_oob) &: $(obj)/xe_gen_wa_oob $(srctree)/$(src)/xe_wa_oob.rules +$(obj)/generated/%_wa_oob.c $(obj)/generated/%_wa_oob.h: $(obj)/xe_gen_wa_oob \ + $(srctree)/$(src)/xe_wa_oob.rules $(call cmd,wa_oob) uses_generated_oob := \ @@ -161,8 +162,8 @@ -Ddrm_i915_gem_object=xe_bo \ -Ddrm_i915_private=xe_device -CFLAGS_i915-display/intel_fbdev.o = $(call cc-disable-warning, override-init) -CFLAGS_i915-display/intel_display_device.o = $(call cc-disable-warning, override-init) +CFLAGS_i915-display/intel_fbdev.o = -Wno-override-init +CFLAGS_i915-display/intel_display_device.o = -Wno-override-init # Rule to build SOC code shared with i915 $(obj)/i915-soc/%.o: $(srctree)/drivers/gpu/drm/i915/soc/%.c FORCE --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -84,7 +84,8 @@ #define IS_ROCKETLAKE(dev_priv) IS_PLATFORM(dev_priv, XE_ROCKETLAKE) #define IS_DG1(dev_priv) IS_PLATFORM(dev_priv, XE_DG1) #define IS_ALDERLAKE_S(dev_priv) IS_PLATFORM(dev_priv, XE_ALDERLAKE_S) -#define IS_ALDERLAKE_P(dev_priv) IS_PLATFORM(dev_priv, XE_ALDERLAKE_P) +#define IS_ALDERLAKE_P(dev_priv) (IS_PLATFORM(dev_priv, XE_ALDERLAKE_P) || \ + IS_PLATFORM(dev_priv, XE_ALDERLAKE_N)) #define IS_XEHPSDV(dev_priv) (dev_priv && 0) #define IS_DG2(dev_priv) IS_PLATFORM(dev_priv, XE_DG2) #define IS_PONTEVECCHIO(dev_priv) IS_PLATFORM(dev_priv, XE_PVC) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/display/intel_fb_bo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/display/intel_fb_bo.c @@ -31,7 +31,7 @@ ret = ttm_bo_reserve(&bo->ttm, true, false, NULL); if (ret) - return ret; + goto err; if (!(bo->flags & XE_BO_SCANOUT_BIT)) { /* @@ -42,12 +42,16 @@ */ if (XE_IOCTL_DBG(i915, !list_empty(&bo->ttm.base.gpuva.list))) { ttm_bo_unreserve(&bo->ttm); - return -EINVAL; + ret = -EINVAL; + goto err; } bo->flags |= XE_BO_SCANOUT_BIT; } ttm_bo_unreserve(&bo->ttm); + return 0; +err: + xe_bo_put(bo); return ret; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/regs/xe_engine_regs.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/regs/xe_engine_regs.h @@ -120,7 +120,7 @@ #define RING_EXECLIST_STATUS_LO(base) XE_REG((base) + 0x234) #define RING_EXECLIST_STATUS_HI(base) XE_REG((base) + 0x234 + 4) -#define RING_CONTEXT_CONTROL(base) XE_REG((base) + 0x244) +#define RING_CONTEXT_CONTROL(base) XE_REG((base) + 0x244, XE_REG_OPTION_MASKED) #define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH REG_BIT(3) #define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT REG_BIT(0) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/tests/xe_dma_buf.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/tests/xe_dma_buf.c @@ -12,6 +12,7 @@ #include "tests/xe_pci_test.h" #include "xe_pci.h" +#include "xe_pm.h" static bool p2p_enabled(struct dma_buf_test_params *params) { @@ -259,6 +260,7 @@ const struct dma_buf_test_params *params; struct kunit *test = xe_cur_kunit(); + xe_pm_runtime_get(xe); for (params = test_params; params->mem_mask; ++params) { struct dma_buf_test_params p = *params; @@ -266,6 +268,7 @@ test->priv = &p; xe_test_dmabuf_import_same_driver(xe); } + xe_pm_runtime_put(xe); /* A non-zero return would halt iteration over driver devices */ return 0; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/tests/xe_migrate.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/tests/xe_migrate.c @@ -114,21 +114,21 @@ region | XE_BO_NEEDS_CPU_ACCESS); if (IS_ERR(remote)) { - KUNIT_FAIL(test, "Failed to allocate remote bo for %s: %li\n", - str, PTR_ERR(remote)); + KUNIT_FAIL(test, "Failed to allocate remote bo for %s: %pe\n", + str, remote); return; } err = xe_bo_validate(remote, NULL, false); if (err) { - KUNIT_FAIL(test, "Failed to validate system bo for %s: %li\n", + KUNIT_FAIL(test, "Failed to validate system bo for %s: %i\n", str, err); goto out_unlock; } err = xe_bo_vmap(remote); if (err) { - KUNIT_FAIL(test, "Failed to vmap system bo for %s: %li\n", + KUNIT_FAIL(test, "Failed to vmap system bo for %s: %i\n", str, err); goto out_unlock; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_bb.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_bb.c @@ -96,7 +96,8 @@ { u64 addr = xe_sa_bo_gpu_addr(bb->bo); - xe_gt_assert(q->gt, !(q->vm && q->vm->flags & XE_VM_FLAG_MIGRATION)); + xe_gt_assert(q->gt, !xe_sched_job_is_migration(q)); + xe_gt_assert(q->gt, q->width == 1); return __xe_bb_create_job(q, bb, &addr); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_bo.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_bo.c @@ -140,9 +140,6 @@ .mem_type = XE_PL_TT, }; *c += 1; - - if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID) - bo->props.preferred_mem_type = XE_PL_TT; } } @@ -177,25 +174,15 @@ } places[*c] = place; *c += 1; - - if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID) - bo->props.preferred_mem_type = mem_type; } static void try_add_vram(struct xe_device *xe, struct xe_bo *bo, u32 bo_flags, u32 *c) { - if (bo->props.preferred_gt == XE_GT1) { - if (bo_flags & XE_BO_CREATE_VRAM1_BIT) - add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c); - if (bo_flags & XE_BO_CREATE_VRAM0_BIT) - add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c); - } else { - if (bo_flags & XE_BO_CREATE_VRAM0_BIT) - add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c); - if (bo_flags & XE_BO_CREATE_VRAM1_BIT) - add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c); - } + if (bo_flags & XE_BO_CREATE_VRAM0_BIT) + add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c); + if (bo_flags & XE_BO_CREATE_VRAM1_BIT) + add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c); } static void try_add_stolen(struct xe_device *xe, struct xe_bo *bo, @@ -219,17 +206,8 @@ { u32 c = 0; - bo->props.preferred_mem_type = XE_BO_PROPS_INVALID; - - /* The order of placements should indicate preferred location */ - - if (bo->props.preferred_mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM) { - try_add_system(xe, bo, bo_flags, &c); - try_add_vram(xe, bo, bo_flags, &c); - } else { - try_add_vram(xe, bo, bo_flags, &c); - try_add_system(xe, bo, bo_flags, &c); - } + try_add_vram(xe, bo, bo_flags, &c); + try_add_system(xe, bo, bo_flags, &c); try_add_stolen(xe, bo, bo_flags, &c); if (!c) @@ -1106,19 +1084,12 @@ } } -static bool should_migrate_to_system(struct xe_bo *bo) -{ - struct xe_device *xe = xe_bo_device(bo); - - return xe_device_in_fault_mode(xe) && bo->props.cpu_atomic; -} - static vm_fault_t xe_gem_fault(struct vm_fault *vmf) { struct ttm_buffer_object *tbo = vmf->vma->vm_private_data; struct drm_device *ddev = tbo->base.dev; vm_fault_t ret; - int idx, r = 0; + int idx; ret = ttm_bo_vm_reserve(tbo, vmf); if (ret) @@ -1129,17 +1100,8 @@ trace_xe_bo_cpu_fault(bo); - if (should_migrate_to_system(bo)) { - r = xe_bo_migrate(bo, XE_PL_TT); - if (r == -EBUSY || r == -ERESTARTSYS || r == -EINTR) - ret = VM_FAULT_NOPAGE; - else if (r) - ret = VM_FAULT_SIGBUS; - } - if (!ret) - ret = ttm_bo_vm_fault_reserved(vmf, - vmf->vma->vm_page_prot, - TTM_BO_VM_NUM_PREFAULT); + ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, + TTM_BO_VM_NUM_PREFAULT); drm_dev_exit(idx); } else { ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot); @@ -1253,9 +1215,6 @@ bo->flags = flags; bo->cpu_caching = cpu_caching; bo->ttm.base.funcs = &xe_gem_object_funcs; - bo->props.preferred_mem_class = XE_BO_PROPS_INVALID; - bo->props.preferred_gt = XE_BO_PROPS_INVALID; - bo->props.preferred_mem_type = XE_BO_PROPS_INVALID; bo->ttm.priority = XE_BO_PRIORITY_NORMAL; INIT_LIST_HEAD(&bo->pinned_link); #ifdef CONFIG_PROC_FS --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_bo_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_bo_types.h @@ -56,25 +56,6 @@ */ struct list_head client_link; #endif - /** @props: BO user controlled properties */ - struct { - /** @preferred_mem: preferred memory class for this BO */ - s16 preferred_mem_class; - /** @prefered_gt: preferred GT for this BO */ - s16 preferred_gt; - /** @preferred_mem_type: preferred memory type */ - s32 preferred_mem_type; - /** - * @cpu_atomic: the CPU expects to do atomics operations to - * this BO - */ - bool cpu_atomic; - /** - * @device_atomic: the device expects to do atomics operations - * to this BO - */ - bool device_atomic; - } props; /** @freed: List node for delayed put. */ struct llist_node freed; /** @created: Whether the bo has passed initial creation */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_devcoredump.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_devcoredump.c @@ -62,16 +62,19 @@ size_t count, void *data, size_t datalen) { struct xe_devcoredump *coredump = data; + struct xe_device *xe; struct xe_devcoredump_snapshot *ss; struct drm_printer p; struct drm_print_iterator iter; struct timespec64 ts; int i; - /* Our device is gone already... */ - if (!data || !coredump_to_xe(coredump)) + if (!coredump) return -ENODEV; + xe = coredump_to_xe(coredump); + ss = &coredump->snapshot; + iter.data = buffer; iter.offset = 0; iter.start = offset; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_device.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_device.c @@ -377,8 +377,14 @@ return err; } -/* - * Initialize MMIO resources that don't require any knowledge about tile count. +/** + * xe_device_probe_early: Device early probe + * @xe: xe device instance + * + * Initialize MMIO resources that don't require any + * knowledge about tile count. Also initialize pcode + * + * Return: 0 on success, error code on failure */ int xe_device_probe_early(struct xe_device *xe) { @@ -392,6 +398,10 @@ if (err) return err; + err = xe_pcode_probe_early(xe); + if (err) + return err; + return 0; } @@ -454,11 +464,8 @@ if (err) return err; - for_each_gt(gt, xe, id) { - err = xe_pcode_probe(gt); - if (err) - return err; - } + for_each_gt(gt, xe, id) + xe_pcode_init(gt); err = xe_display_init_noirq(xe); if (err) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_device.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_device.h @@ -58,7 +58,7 @@ static inline struct xe_gt *xe_tile_get_gt(struct xe_tile *tile, u8 gt_id) { - if (drm_WARN_ON(&tile_to_xe(tile)->drm, gt_id > XE_MAX_GT_PER_TILE)) + if (drm_WARN_ON(&tile_to_xe(tile)->drm, gt_id >= XE_MAX_GT_PER_TILE)) gt_id = 0; return gt_id ? tile->media_gt : tile->primary_gt; @@ -79,7 +79,7 @@ if (MEDIA_VER(xe) >= 13) { gt = xe_tile_get_gt(root_tile, gt_id); } else { - if (drm_WARN_ON(&xe->drm, gt_id > XE_MAX_TILES_PER_DEVICE)) + if (drm_WARN_ON(&xe->drm, gt_id >= XE_MAX_TILES_PER_DEVICE)) gt_id = 0; gt = xe->tiles[gt_id].primary_gt; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_display.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_display.c @@ -108,11 +108,6 @@ xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0); drmm_mutex_init(&xe->drm, &xe->sb_lock); - drmm_mutex_init(&xe->drm, &xe->display.backlight.lock); - drmm_mutex_init(&xe->drm, &xe->display.audio.mutex); - drmm_mutex_init(&xe->drm, &xe->display.wm.wm_mutex); - drmm_mutex_init(&xe->drm, &xe->display.pps.mutex); - drmm_mutex_init(&xe->drm, &xe->display.hdcp.hdcp_mutex); xe->enabled_irq_mask = ~0; err = drmm_add_action_or_reset(&xe->drm, display_destroy, NULL); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_exec.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_exec.c @@ -113,7 +113,6 @@ struct drm_exec *exec = &vm_exec.exec; u32 i, num_syncs = 0, num_ufence = 0; struct xe_sched_job *job; - struct dma_fence *rebind_fence; struct xe_vm *vm; bool write_locked, skip_retry = false; ktime_t end = 0; @@ -196,6 +195,29 @@ goto err_unlock_list; } + if (!args->num_batch_buffer) { + err = xe_vm_lock(vm, true); + if (err) + goto err_unlock_list; + + if (!xe_vm_in_lr_mode(vm)) { + struct dma_fence *fence; + + fence = xe_sync_in_fence_get(syncs, num_syncs, q, vm); + if (IS_ERR(fence)) { + err = PTR_ERR(fence); + goto err_unlock_list; + } + for (i = 0; i < num_syncs; i++) + xe_sync_entry_signal(&syncs[i], NULL, fence); + xe_exec_queue_last_fence_set(q, vm, fence); + dma_fence_put(fence); + } + + xe_vm_unlock(vm); + goto err_unlock_list; + } + vm_exec.vm = &vm->gpuvm; vm_exec.num_fences = 1 + vm->xe->info.tile_count; vm_exec.flags = DRM_EXEC_INTERRUPTIBLE_WAIT; @@ -216,24 +238,6 @@ goto err_exec; } - if (!args->num_batch_buffer) { - if (!xe_vm_in_lr_mode(vm)) { - struct dma_fence *fence; - - fence = xe_sync_in_fence_get(syncs, num_syncs, q, vm); - if (IS_ERR(fence)) { - err = PTR_ERR(fence); - goto err_exec; - } - for (i = 0; i < num_syncs; i++) - xe_sync_entry_signal(&syncs[i], NULL, fence); - xe_exec_queue_last_fence_set(q, vm, fence); - dma_fence_put(fence); - } - - goto err_exec; - } - if (xe_exec_queue_is_lr(q) && xe_exec_queue_ring_full(q)) { err = -EWOULDBLOCK; /* Aliased to -EAGAIN */ skip_retry = true; @@ -251,35 +255,11 @@ * Rebind any invalidated userptr or evicted BOs in the VM, non-compute * VM mode only. */ - rebind_fence = xe_vm_rebind(vm, false); - if (IS_ERR(rebind_fence)) { - err = PTR_ERR(rebind_fence); + err = xe_vm_rebind(vm, false); + if (err) goto err_put_job; - } - - /* - * We store the rebind_fence in the VM so subsequent execs don't get - * scheduled before the rebinds of userptrs / evicted BOs is complete. - */ - if (rebind_fence) { - dma_fence_put(vm->rebind_fence); - vm->rebind_fence = rebind_fence; - } - if (vm->rebind_fence) { - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, - &vm->rebind_fence->flags)) { - dma_fence_put(vm->rebind_fence); - vm->rebind_fence = NULL; - } else { - dma_fence_get(vm->rebind_fence); - err = drm_sched_job_add_dependency(&job->drm, - vm->rebind_fence); - if (err) - goto err_put_job; - } - } - /* Wait behind munmap style rebinds */ + /* Wait behind rebinds */ if (!xe_vm_in_lr_mode(vm)) { err = drm_sched_job_add_resv_dependencies(&job->drm, xe_vm_resv(vm), --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_exec_queue.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_exec_queue.c @@ -66,6 +66,8 @@ q->sched_props.timeslice_us = hwe->eclass->sched_props.timeslice_us; q->sched_props.preempt_timeout_us = hwe->eclass->sched_props.preempt_timeout_us; + q->sched_props.job_timeout_ms = + hwe->eclass->sched_props.job_timeout_ms; if (q->flags & EXEC_QUEUE_FLAG_KERNEL && q->flags & EXEC_QUEUE_FLAG_HIGH_PRIORITY) q->sched_props.priority = XE_EXEC_QUEUE_PRIORITY_KERNEL; @@ -403,7 +405,7 @@ { u32 idx; - if (eci.engine_class > ARRAY_SIZE(user_to_xe_engine_class)) + if (eci.engine_class >= ARRAY_SIZE(user_to_xe_engine_class)) return NULL; if (eci.gt_id >= xe->info.gt_count) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_exec_queue_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_exec_queue_types.h @@ -132,6 +132,8 @@ u32 timeslice_us; /** @preempt_timeout_us: preemption timeout in micro-seconds */ u32 preempt_timeout_us; + /** @job_timeout_ms: job timeout in milliseconds */ + u32 job_timeout_ms; /** @priority: priority of this exec queue */ enum xe_exec_queue_priority priority; } sched_props; @@ -157,6 +159,11 @@ const struct xe_ring_ops *ring_ops; /** @entity: DRM sched entity for this exec queue (1 to 1 relationship) */ struct drm_sched_entity *entity; + /** + * @tlb_flush_seqno: The seqno of the last rebind tlb flush performed + * Protected by @vm's resv. Unused if @vm == NULL. + */ + u64 tlb_flush_seqno; /** @lrc: logical ring context for this exec queue */ struct xe_lrc lrc[]; }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_gt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_gt.c @@ -384,7 +384,9 @@ err); /* Initialize CCS mode sysfs after early initialization of HW engines */ - xe_gt_ccs_mode_sysfs_init(gt); + err = xe_gt_ccs_mode_sysfs_init(gt); + if (err) + goto err_force_wake; err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); XE_WARN_ON(err); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_ccs_mode.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_gt_ccs_mode.c @@ -167,25 +167,20 @@ * and it is expected that there are no open drm clients while doing so. * The number of available compute slices is exposed to user through a per-gt * 'num_cslices' sysfs interface. + * + * Returns: Returns error value for failure and 0 for success. */ -void xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt) +int xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); int err; if (!xe_gt_ccs_mode_enabled(gt)) - return; + return 0; err = sysfs_create_files(gt->sysfs, gt_ccs_mode_attrs); - if (err) { - drm_warn(&xe->drm, "Sysfs creation for ccs_mode failed err: %d\n", err); - return; - } + if (err) + return err; - err = drmm_add_action_or_reset(&xe->drm, xe_gt_ccs_mode_sysfs_fini, gt); - if (err) { - sysfs_remove_files(gt->sysfs, gt_ccs_mode_attrs); - drm_warn(&xe->drm, "%s: drmm_add_action_or_reset failed, err: %d\n", - __func__, err); - } + return drmm_add_action_or_reset(&xe->drm, xe_gt_ccs_mode_sysfs_fini, gt); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_ccs_mode.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_gt_ccs_mode.h @@ -12,7 +12,7 @@ #include "xe_platform_types.h" void xe_gt_apply_ccs_mode(struct xe_gt *gt); -void xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt); +int xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt); static inline bool xe_gt_ccs_mode_enabled(const struct xe_gt *gt) { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_idle.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_gt_idle.c @@ -126,6 +126,13 @@ static void gt_idle_sysfs_fini(struct drm_device *drm, void *arg) { struct kobject *kobj = arg; + struct xe_gt *gt = kobj_to_gt(kobj->parent); + + if (gt_to_xe(gt)->info.skip_guc_pc) { + XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT)); + xe_gt_idle_disable_c6(gt); + xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); + } sysfs_remove_files(kobj, gt_idle_attrs); kobject_put(kobj); @@ -184,7 +191,7 @@ void xe_gt_idle_disable_c6(struct xe_gt *gt) { xe_device_assert_mem_access(gt_to_xe(gt)); - xe_force_wake_assert_held(gt_to_fw(gt), XE_FORCEWAKE_ALL); + xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT); xe_mmio_write32(gt, PG_ENABLE, 0); xe_mmio_write32(gt, RC_CONTROL, 0); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_mcr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -312,7 +312,7 @@ else gt->steering[OADDRM].group_target = 1; - gt->steering[DSS].instance_target = 0; /* unused */ + gt->steering[OADDRM].instance_target = 0; /* unused */ } static void init_steering_sqidi_psmi(struct xe_gt *gt) @@ -327,8 +327,8 @@ static void init_steering_inst0(struct xe_gt *gt) { - gt->steering[DSS].group_target = 0; /* unused */ - gt->steering[DSS].instance_target = 0; /* unused */ + gt->steering[INSTANCE0].group_target = 0; /* unused */ + gt->steering[INSTANCE0].instance_target = 0; /* unused */ } static const struct { --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_pagefault.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_gt_pagefault.c @@ -69,7 +69,7 @@ static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma) { return BIT(tile->id) & vma->tile_present && - !(BIT(tile->id) & vma->usm.tile_invalidated); + !(BIT(tile->id) & vma->tile_invalidated); } static bool vma_matches(struct xe_vma *vma, u64 page_addr) @@ -146,10 +146,12 @@ /* ASID to VM */ mutex_lock(&xe->usm.lock); vm = xa_load(&xe->usm.asid_to_vm, pf->asid); - if (vm) + if (vm && xe_vm_in_fault_mode(vm)) xe_vm_get(vm); + else + vm = NULL; mutex_unlock(&xe->usm.lock); - if (!vm || !xe_vm_in_fault_mode(vm)) + if (!vm) return -EINVAL; retry_userptr: @@ -224,7 +226,7 @@ if (xe_vma_is_userptr(vma)) ret = xe_vma_userptr_check_repin(to_userptr_vma(vma)); - vma->usm.tile_invalidated &= ~BIT(tile->id); + vma->tile_invalidated &= ~BIT(tile->id); unlock_dma_resv: drm_exec_fini(&exec); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_pc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_guc_pc.c @@ -381,8 +381,6 @@ struct xe_device *xe = gt_to_xe(gt); u32 freq; - xe_device_mem_access_get(gt_to_xe(gt)); - /* When in RC6, actual frequency reported will be 0. */ if (GRAPHICS_VERx100(xe) >= 1270) { freq = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1); @@ -394,8 +392,6 @@ freq = decode_freq(freq); - xe_device_mem_access_put(gt_to_xe(gt)); - return freq; } @@ -412,14 +408,13 @@ struct xe_gt *gt = pc_to_gt(pc); int ret; - xe_device_mem_access_get(gt_to_xe(gt)); /* * GuC SLPC plays with cur freq request when GuCRC is enabled * Block RC6 for a more reliable read. */ ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); if (ret) - goto out; + return ret; *freq = xe_mmio_read32(gt, RPNSWREQ); @@ -427,9 +422,7 @@ *freq = decode_freq(*freq); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL)); -out: - xe_device_mem_access_put(gt_to_xe(gt)); - return ret; + return 0; } /** @@ -451,12 +444,7 @@ */ u32 xe_guc_pc_get_rpe_freq(struct xe_guc_pc *pc) { - struct xe_gt *gt = pc_to_gt(pc); - struct xe_device *xe = gt_to_xe(gt); - - xe_device_mem_access_get(xe); pc_update_rp_values(pc); - xe_device_mem_access_put(xe); return pc->rpe_freq; } @@ -485,7 +473,6 @@ struct xe_gt *gt = pc_to_gt(pc); int ret; - xe_device_mem_access_get(pc_to_xe(pc)); mutex_lock(&pc->freq_lock); if (!pc->freq_ready) { /* Might be in the middle of a gt reset */ @@ -511,7 +498,6 @@ XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL)); out: mutex_unlock(&pc->freq_lock); - xe_device_mem_access_put(pc_to_xe(pc)); return ret; } @@ -528,7 +514,6 @@ { int ret; - xe_device_mem_access_get(pc_to_xe(pc)); mutex_lock(&pc->freq_lock); if (!pc->freq_ready) { /* Might be in the middle of a gt reset */ @@ -544,8 +529,6 @@ out: mutex_unlock(&pc->freq_lock); - xe_device_mem_access_put(pc_to_xe(pc)); - return ret; } @@ -561,7 +544,6 @@ { int ret; - xe_device_mem_access_get(pc_to_xe(pc)); mutex_lock(&pc->freq_lock); if (!pc->freq_ready) { /* Might be in the middle of a gt reset */ @@ -577,7 +559,6 @@ out: mutex_unlock(&pc->freq_lock); - xe_device_mem_access_put(pc_to_xe(pc)); return ret; } @@ -594,7 +575,6 @@ { int ret; - xe_device_mem_access_get(pc_to_xe(pc)); mutex_lock(&pc->freq_lock); if (!pc->freq_ready) { /* Might be in the middle of a gt reset */ @@ -610,7 +590,6 @@ out: mutex_unlock(&pc->freq_lock); - xe_device_mem_access_put(pc_to_xe(pc)); return ret; } @@ -623,8 +602,6 @@ struct xe_gt *gt = pc_to_gt(pc); u32 reg, gt_c_state; - xe_device_mem_access_get(gt_to_xe(gt)); - if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) { reg = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1); gt_c_state = REG_FIELD_GET(MTL_CC_MASK, reg); @@ -633,8 +610,6 @@ gt_c_state = REG_FIELD_GET(RCN_MASK, reg); } - xe_device_mem_access_put(gt_to_xe(gt)); - switch (gt_c_state) { case GT_C6: return GT_IDLE_C6; @@ -654,9 +629,7 @@ struct xe_gt *gt = pc_to_gt(pc); u32 reg; - xe_device_mem_access_get(gt_to_xe(gt)); reg = xe_mmio_read32(gt, GT_GFX_RC6); - xe_device_mem_access_put(gt_to_xe(gt)); return reg; } @@ -670,9 +643,7 @@ struct xe_gt *gt = pc_to_gt(pc); u64 reg; - xe_device_mem_access_get(gt_to_xe(gt)); reg = xe_mmio_read32(gt, MTL_MEDIA_MC6); - xe_device_mem_access_put(gt_to_xe(gt)); return reg; } @@ -801,23 +772,19 @@ if (xe->info.skip_guc_pc) return 0; - xe_device_mem_access_get(pc_to_xe(pc)); - ret = pc_action_setup_gucrc(pc, XE_GUCRC_HOST_CONTROL); if (ret) - goto out; + return ret; ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); if (ret) - goto out; + return ret; xe_gt_idle_disable_c6(gt); XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL)); -out: - xe_device_mem_access_put(pc_to_xe(pc)); - return ret; + return 0; } static void pc_init_pcode_freq(struct xe_guc_pc *pc) @@ -870,11 +837,9 @@ xe_gt_assert(gt, xe_device_uc_enabled(xe)); - xe_device_mem_access_get(pc_to_xe(pc)); - ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); if (ret) - goto out_fail_force_wake; + return ret; if (xe->info.skip_guc_pc) { if (xe->info.platform != XE_PVC) @@ -914,8 +879,6 @@ out: XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL)); -out_fail_force_wake: - xe_device_mem_access_put(pc_to_xe(pc)); return ret; } @@ -928,12 +891,9 @@ struct xe_device *xe = pc_to_xe(pc); int ret; - xe_device_mem_access_get(pc_to_xe(pc)); - if (xe->info.skip_guc_pc) { xe_gt_idle_disable_c6(pc_to_gt(pc)); - ret = 0; - goto out; + return 0; } mutex_lock(&pc->freq_lock); @@ -942,16 +902,14 @@ ret = pc_action_shutdown(pc); if (ret) - goto out; + return ret; if (wait_for_pc_state(pc, SLPC_GLOBAL_STATE_NOT_RUNNING)) { drm_err(&pc_to_xe(pc)->drm, "GuC PC Shutdown failed\n"); - ret = -EIO; + return -EIO; } -out: - xe_device_mem_access_put(pc_to_xe(pc)); - return ret; + return 0; } /** @@ -960,15 +918,6 @@ */ void xe_guc_pc_fini(struct xe_guc_pc *pc) { - struct xe_device *xe = pc_to_xe(pc); - - if (xe->info.skip_guc_pc) { - xe_device_mem_access_get(xe); - xe_gt_idle_disable_c6(pc_to_gt(pc)); - xe_device_mem_access_put(xe); - return; - } - XE_WARN_ON(xe_guc_pc_gucrc_disable(pc)); XE_WARN_ON(xe_guc_pc_stop(pc)); mutex_destroy(&pc->freq_lock); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_submit.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1216,7 +1216,7 @@ init_waitqueue_head(&ge->suspend_wait); timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : - q->hwe->eclass->sched_props.job_timeout_ms; + msecs_to_jiffies(q->sched_props.job_timeout_ms); err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, get_submit_wq(guc), q->lrc[0].ring.size / MAX_JOB_SIZE_BYTES, 64, @@ -1253,6 +1253,7 @@ return 0; err_entity: + mutex_unlock(&guc->submission_state.lock); xe_sched_entity_fini(&ge->entity); err_sched: xe_sched_fini(&ge->sched); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_huc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_huc.c @@ -53,7 +53,6 @@ struct xe_gt *gt = huc_to_gt(huc); struct xe_device *xe = gt_to_xe(gt); struct xe_bo *bo; - int err; /* we use a single object for both input and output */ bo = xe_bo_create_pin_map(xe, gt_to_tile(gt), NULL, @@ -66,13 +65,7 @@ huc->gsc_pkt = bo; - err = drmm_add_action_or_reset(&xe->drm, free_gsc_pkt, huc); - if (err) { - free_gsc_pkt(&xe->drm, huc); - return err; - } - - return 0; + return drmm_add_action_or_reset(&xe->drm, free_gsc_pkt, huc); } int xe_huc_init(struct xe_huc *huc) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_hwmon.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_hwmon.c @@ -288,7 +288,7 @@ * As y can be < 2, we compute tau4 = (4 | x) << y * and then add 2 when doing the final right shift to account for units */ - tau4 = ((1 << x_w) | x) << y; + tau4 = (u64)((1 << x_w) | x) << y; /* val in hwmon interface units (millisec) */ out = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w); @@ -328,7 +328,7 @@ r = FIELD_PREP(PKG_MAX_WIN, PKG_MAX_WIN_DEFAULT); x = REG_FIELD_GET(PKG_MAX_WIN_X, r); y = REG_FIELD_GET(PKG_MAX_WIN_Y, r); - tau4 = ((1 << x_w) | x) << y; + tau4 = (u64)((1 << x_w) | x) << y; max_win = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w); if (val > max_win) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_lrc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_lrc.c @@ -95,7 +95,6 @@ #define REG16(x) \ (((x) >> 9) | BIT(7) | BUILD_BUG_ON_ZERO(x >= 0x10000)), \ (((x) >> 2) & 0x7f) -#define END 0 { const u32 base = hwe->mmio_base; @@ -166,7 +165,7 @@ REG16(0x274), REG16(0x270), - END + 0 }; static const u8 dg2_xcs_offsets[] = { @@ -200,7 +199,7 @@ REG16(0x274), REG16(0x270), - END + 0 }; static const u8 gen12_rcs_offsets[] = { @@ -296,7 +295,7 @@ REG(0x084), NOP(1), - END + 0 }; static const u8 xehp_rcs_offsets[] = { @@ -337,7 +336,7 @@ LRI(1, 0), REG(0x0c8), - END + 0 }; static const u8 dg2_rcs_offsets[] = { @@ -380,7 +379,7 @@ LRI(1, 0), REG(0x0c8), - END + 0 }; static const u8 mtl_rcs_offsets[] = { @@ -423,7 +422,7 @@ LRI(1, 0), REG(0x0c8), - END + 0 }; #define XE2_CTX_COMMON \ @@ -469,7 +468,7 @@ LRI(1, 0), /* [0x47] */ REG(0x0c8), /* [0x48] R_PWR_CLK_STATE */ - END + 0 }; static const u8 xe2_bcs_offsets[] = { @@ -480,16 +479,15 @@ REG16(0x200), /* [0x42] BCS_SWCTRL */ REG16(0x204), /* [0x44] BLIT_CCTL */ - END + 0 }; static const u8 xe2_xcs_offsets[] = { XE2_CTX_COMMON, - END + 0 }; -#undef END #undef REG16 #undef REG #undef LRI @@ -525,9 +523,8 @@ static void set_context_control(u32 *regs, struct xe_hw_engine *hwe) { - regs[CTX_CONTEXT_CONTROL] = _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH) | - _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) | - CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT; + regs[CTX_CONTEXT_CONTROL] = _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | + CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); /* TODO: Timestamp */ } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_migrate.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_migrate.c @@ -32,7 +32,6 @@ #include "xe_sync.h" #include "xe_trace.h" #include "xe_vm.h" -#include "xe_wa.h" /** * struct xe_migrate - migrate context. @@ -216,7 +215,7 @@ if (vm->flags & XE_VM_FLAG_64K && level == 1) flags = XE_PDE_64K; - entry = vm->pt_ops->pde_encode_bo(bo, map_ofs + (level - 1) * + entry = vm->pt_ops->pde_encode_bo(bo, map_ofs + (u64)(level - 1) * XE_PAGE_SIZE, pat_index); xe_map_wr(xe, &bo->vmap, map_ofs + XE_PAGE_SIZE * level, u64, entry | flags); @@ -224,7 +223,7 @@ /* Write PDE's that point to our BO. */ for (i = 0; i < num_entries - num_level; i++) { - entry = vm->pt_ops->pde_encode_bo(bo, i * XE_PAGE_SIZE, + entry = vm->pt_ops->pde_encode_bo(bo, (u64)i * XE_PAGE_SIZE, pat_index); xe_map_wr(xe, &bo->vmap, map_ofs + XE_PAGE_SIZE + @@ -280,7 +279,7 @@ #define VM_SA_UPDATE_UNIT_SIZE (XE_PAGE_SIZE / NUM_VMUSA_UNIT_PER_PAGE) #define NUM_VMUSA_WRITES_PER_UNIT (VM_SA_UPDATE_UNIT_SIZE / sizeof(u64)) drm_suballoc_manager_init(&m->vm_update_sa, - (map_ofs / XE_PAGE_SIZE - NUM_KERNEL_PDE) * + (size_t)(map_ofs / XE_PAGE_SIZE - NUM_KERNEL_PDE) * NUM_VMUSA_UNIT_PER_PAGE, 0); m->pt_bo = bo; @@ -288,10 +287,6 @@ } /* - * Due to workaround 16017236439, odd instance hardware copy engines are - * faster than even instance ones. - * This function returns the mask involving all fast copy engines and the - * reserved copy engine to be used as logical mask for migrate engine. * Including the reserved copy engine is required to avoid deadlocks due to * migrate jobs servicing the faults gets stuck behind the job that faulted. */ @@ -305,8 +300,7 @@ if (hwe->class != XE_ENGINE_CLASS_COPY) continue; - if (!XE_WA(gt, 16017236439) || - xe_gt_is_usm_hwe(gt, hwe) || hwe->instance & 1) + if (xe_gt_is_usm_hwe(gt, hwe)) logical_mask |= BIT(hwe->logical_instance); } @@ -357,6 +351,10 @@ if (!hwe || !logical_mask) return ERR_PTR(-EINVAL); + /* + * XXX: Currently only reserving 1 (likely slow) BCS instance on + * PVC, may want to revisit if performance is needed. + */ m->q = xe_exec_queue_create(xe, vm, logical_mask, 1, hwe, EXEC_QUEUE_FLAG_KERNEL | EXEC_QUEUE_FLAG_PERMANENT | @@ -479,7 +477,7 @@ struct xe_vm *vm = m->q->vm; u16 pat_index; u32 ptes; - u64 ofs = at_pt * XE_PAGE_SIZE; + u64 ofs = (u64)at_pt * XE_PAGE_SIZE; u64 cur_ofs; /* Indirect access needs compression enabled uncached PAT index */ @@ -1327,7 +1325,7 @@ GFP_KERNEL, true, 0); if (IS_ERR(sa_bo)) { err = PTR_ERR(sa_bo); - goto err; + goto err_bb; } ppgtt_ofs = NUM_KERNEL_PDE + @@ -1378,7 +1376,7 @@ update_idx); if (IS_ERR(job)) { err = PTR_ERR(job); - goto err_bb; + goto err_sa; } /* Wait on BO move */ @@ -1427,12 +1425,12 @@ err_job: xe_sched_job_put(job); +err_sa: + drm_suballoc_free(sa_bo, NULL); err_bb: if (!q) mutex_unlock(&m->job_mutex); xe_bb_free(bb, NULL); -err: - drm_suballoc_free(sa_bo, NULL); return ERR_PTR(err); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_pat.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_pat.c @@ -452,7 +452,7 @@ { struct xe_device *xe = gt_to_xe(gt); - if (!xe->pat.ops->dump) + if (!xe->pat.ops) return; xe->pat.ops->dump(gt, p); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_pcode.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_pcode.c @@ -10,6 +10,7 @@ #include +#include "xe_device.h" #include "xe_gt.h" #include "xe_mmio.h" #include "xe_pcode_api.h" @@ -43,8 +44,6 @@ [PCODE_ERROR_MASK] = {-EPROTO, "Unknown"}, }; - lockdep_assert_held(>->pcode.lock); - err = xe_mmio_read32(gt, PCODE_MAILBOX) & PCODE_ERROR_MASK; if (err) { drm_err(>_to_xe(gt)->drm, "PCODE Mailbox failed: %d %s", err, @@ -55,17 +54,15 @@ return 0; } -static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1, - unsigned int timeout_ms, bool return_data, - bool atomic) +static int __pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1, + unsigned int timeout_ms, bool return_data, + bool atomic) { int err; if (gt_to_xe(gt)->info.skip_pcode) return 0; - lockdep_assert_held(>->pcode.lock); - if ((xe_mmio_read32(gt, PCODE_MAILBOX) & PCODE_READY) != 0) return -EAGAIN; @@ -87,6 +84,18 @@ return pcode_mailbox_status(gt); } +static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1, + unsigned int timeout_ms, bool return_data, + bool atomic) +{ + if (gt_to_xe(gt)->info.skip_pcode) + return 0; + + lockdep_assert_held(>->pcode.lock); + + return __pcode_mailbox_rw(gt, mbox, data0, data1, timeout_ms, return_data, atomic); +} + int xe_pcode_write_timeout(struct xe_gt *gt, u32 mbox, u32 data, int timeout) { int err; @@ -109,15 +118,19 @@ return err; } -static int xe_pcode_try_request(struct xe_gt *gt, u32 mbox, - u32 request, u32 reply_mask, u32 reply, - u32 *status, bool atomic, int timeout_us) +static int pcode_try_request(struct xe_gt *gt, u32 mbox, + u32 request, u32 reply_mask, u32 reply, + u32 *status, bool atomic, int timeout_us, bool locked) { int slept, wait = 10; for (slept = 0; slept < timeout_us; slept += wait) { - *status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true, - atomic); + if (locked) + *status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true, + atomic); + else + *status = __pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true, + atomic); if ((*status == 0) && ((request & reply_mask) == reply)) return 0; @@ -158,8 +171,8 @@ mutex_lock(>->pcode.lock); - ret = xe_pcode_try_request(gt, mbox, request, reply_mask, reply, &status, - false, timeout_base_ms * 1000); + ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status, + false, timeout_base_ms * 1000, true); if (!ret) goto out; @@ -177,8 +190,8 @@ "PCODE timeout, retrying with preemption disabled\n"); drm_WARN_ON_ONCE(>_to_xe(gt)->drm, timeout_base_ms > 1); preempt_disable(); - ret = xe_pcode_try_request(gt, mbox, request, reply_mask, reply, &status, - true, timeout_base_ms * 1000); + ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status, + true, 50 * 1000, true); preempt_enable(); out: @@ -238,59 +251,71 @@ } /** - * xe_pcode_init - Ensure PCODE is initialized - * @gt: gt instance + * xe_pcode_ready - Ensure PCODE is initialized + * @xe: xe instance + * @locked: true if lock held, false otherwise * - * This function ensures that PCODE is properly initialized. To be called during - * probe and resume paths. + * PCODE init mailbox is polled only on root gt of root tile + * as the root tile provides the initialization is complete only + * after all the tiles have completed the initialization. + * Called only on early probe without locks and with locks in + * resume path. * - * It returns 0 on success, and -error number on failure. + * Returns 0 on success, and -error number on failure. */ -int xe_pcode_init(struct xe_gt *gt) +int xe_pcode_ready(struct xe_device *xe, bool locked) { u32 status, request = DGFX_GET_INIT_STATUS; + struct xe_gt *gt = xe_root_mmio_gt(xe); int timeout_us = 180000000; /* 3 min */ int ret; - if (gt_to_xe(gt)->info.skip_pcode) + if (xe->info.skip_pcode) return 0; - if (!IS_DGFX(gt_to_xe(gt))) + if (!IS_DGFX(xe)) return 0; - mutex_lock(>->pcode.lock); - ret = xe_pcode_try_request(gt, DGFX_PCODE_STATUS, request, - DGFX_INIT_STATUS_COMPLETE, - DGFX_INIT_STATUS_COMPLETE, - &status, false, timeout_us); - mutex_unlock(>->pcode.lock); + if (locked) + mutex_lock(>->pcode.lock); + + ret = pcode_try_request(gt, DGFX_PCODE_STATUS, request, + DGFX_INIT_STATUS_COMPLETE, + DGFX_INIT_STATUS_COMPLETE, + &status, false, timeout_us, locked); + + if (locked) + mutex_unlock(>->pcode.lock); if (ret) - drm_err(>_to_xe(gt)->drm, + drm_err(&xe->drm, "PCODE initialization timedout after: 3 min\n"); return ret; } /** - * xe_pcode_probe - Prepare xe_pcode and also ensure PCODE is initialized. + * xe_pcode_init: initialize components of PCODE * @gt: gt instance * - * This function initializes the xe_pcode component, and when needed, it ensures - * that PCODE has properly performed its initialization and it is really ready - * to go. To be called once only during probe. - * - * It returns 0 on success, and -error number on failure. + * This function initializes the xe_pcode component. + * To be called once only during probe. */ -int xe_pcode_probe(struct xe_gt *gt) +void xe_pcode_init(struct xe_gt *gt) { drmm_mutex_init(>_to_xe(gt)->drm, >->pcode.lock); +} - if (gt_to_xe(gt)->info.skip_pcode) - return 0; - - if (!IS_DGFX(gt_to_xe(gt))) - return 0; - - return xe_pcode_init(gt); +/** + * xe_pcode_probe_early: initializes PCODE + * @xe: xe instance + * + * This function checks the initialization status of PCODE + * To be called once only during early probe without locks. + * + * Returns 0 on success, error code otherwise + */ +int xe_pcode_probe_early(struct xe_device *xe) +{ + return xe_pcode_ready(xe, false); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_pcode.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_pcode.h @@ -8,9 +8,11 @@ #include struct xe_gt; +struct xe_device; -int xe_pcode_probe(struct xe_gt *gt); -int xe_pcode_init(struct xe_gt *gt); +void xe_pcode_init(struct xe_gt *gt); +int xe_pcode_probe_early(struct xe_device *xe); +int xe_pcode_ready(struct xe_device *xe, bool locked); int xe_pcode_init_min_freq_table(struct xe_gt *gt, u32 min_gt_freq, u32 max_gt_freq); int xe_pcode_read(struct xe_gt *gt, u32 mbox, u32 *val, u32 *val1); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_pm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_pm.c @@ -54,13 +54,15 @@ u8 id; int err; + drm_dbg(&xe->drm, "Suspending device\n"); + for_each_gt(gt, xe, id) xe_gt_suspend_prepare(gt); /* FIXME: Super racey... */ err = xe_bo_evict_all(xe); if (err) - return err; + goto err; xe_display_pm_suspend(xe); @@ -68,7 +70,7 @@ err = xe_gt_suspend(gt); if (err) { xe_display_pm_resume(xe); - return err; + goto err; } } @@ -76,7 +78,11 @@ xe_display_pm_suspend_late(xe); + drm_dbg(&xe->drm, "Device suspended\n"); return 0; +err: + drm_dbg(&xe->drm, "Device suspend failed %d\n", err); + return err; } /** @@ -92,14 +98,14 @@ u8 id; int err; + drm_dbg(&xe->drm, "Resuming device\n"); + for_each_tile(tile, xe, id) xe_wa_apply_tile_workarounds(tile); - for_each_gt(gt, xe, id) { - err = xe_pcode_init(gt); - if (err) - return err; - } + err = xe_pcode_ready(xe, true); + if (err) + return err; xe_display_pm_resume_early(xe); @@ -109,7 +115,7 @@ */ err = xe_bo_restore_kernel(xe); if (err) - return err; + goto err; xe_irq_resume(xe); @@ -120,9 +126,13 @@ err = xe_bo_restore_user(xe); if (err) - return err; + goto err; + drm_dbg(&xe->drm, "Device resumed\n"); return 0; +err: + drm_dbg(&xe->drm, "Device resume failed %d\n", err); + return err; } static bool xe_pm_pci_d3cold_capable(struct pci_dev *pdev) @@ -286,11 +296,9 @@ xe->d3cold.power_lost = xe_guc_in_reset(>->uc.guc); if (xe->d3cold.allowed && xe->d3cold.power_lost) { - for_each_gt(gt, xe, id) { - err = xe_pcode_init(gt); - if (err) - goto out; - } + err = xe_pcode_ready(xe, true); + if (err) + goto out; /* * This only restores pinned memory which is the memory --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_pt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_pt.c @@ -1255,11 +1255,13 @@ * non-faulting LR, in particular on user-space batch buffer chaining, * it needs to be done here. */ - if ((rebind && !xe_vm_in_lr_mode(vm) && !vm->batch_invalidate_tlb) || - (!rebind && xe_vm_has_scratch(vm) && xe_vm_in_preempt_fence_mode(vm))) { + if ((!rebind && xe_vm_has_scratch(vm) && xe_vm_in_preempt_fence_mode(vm))) { ifence = kzalloc(sizeof(*ifence), GFP_KERNEL); if (!ifence) return ERR_PTR(-ENOMEM); + } else if (rebind && !xe_vm_in_lr_mode(vm)) { + /* We bump also if batch_invalidate_tlb is true */ + vm->tlb_flush_seqno++; } rfence = kzalloc(sizeof(*rfence), GFP_KERNEL); @@ -1298,7 +1300,7 @@ } /* add shared fence now for pagetable delayed destroy */ - dma_resv_add_fence(xe_vm_resv(vm), fence, !rebind && + dma_resv_add_fence(xe_vm_resv(vm), fence, rebind || last_munmap_rebind ? DMA_RESV_USAGE_KERNEL : DMA_RESV_USAGE_BOOKKEEP); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_query.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_query.c @@ -132,7 +132,7 @@ return -EINVAL; eci = &resp.eci; - if (eci->gt_id > XE_MAX_GT_PER_TILE) + if (eci->gt_id >= XE_MAX_GT_PER_TILE) return -EINVAL; gt = xe_device_get_gt(xe, eci->gt_id); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_ring_ops.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_ring_ops.c @@ -78,6 +78,16 @@ return i; } +static int emit_flush_dw(u32 *dw, int i) +{ + dw[i++] = MI_FLUSH_DW | MI_FLUSH_IMM_DW; + dw[i++] = 0; + dw[i++] = 0; + dw[i++] = 0; + + return i; +} + static int emit_flush_imm_ggtt(u32 addr, u32 value, bool invalidate_tlb, u32 *dw, int i) { @@ -227,10 +237,9 @@ { u32 dw[MAX_JOB_SIZE_DW], i = 0; u32 ppgtt_flag = get_ppgtt_flag(job); - struct xe_vm *vm = job->q->vm; struct xe_gt *gt = job->q->gt; - if (vm && vm->batch_invalidate_tlb) { + if (job->ring_ops_flush_tlb) { dw[i++] = preparser_disable(true); i = emit_flush_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc), seqno, true, dw, i); @@ -242,10 +251,12 @@ i = emit_bb_start(batch_addr, ppgtt_flag, dw, i); - if (job->user_fence.used) + if (job->user_fence.used) { + i = emit_flush_dw(dw, i); i = emit_store_imm_ppgtt_posted(job->user_fence.addr, job->user_fence.value, dw, i); + } i = emit_flush_imm_ggtt(xe_lrc_seqno_ggtt_addr(lrc), seqno, false, dw, i); @@ -278,7 +289,6 @@ struct xe_gt *gt = job->q->gt; struct xe_device *xe = gt_to_xe(gt); bool decode = job->q->class == XE_ENGINE_CLASS_VIDEO_DECODE; - struct xe_vm *vm = job->q->vm; dw[i++] = preparser_disable(true); @@ -290,22 +300,24 @@ i = emit_aux_table_inv(gt, VE0_AUX_INV, dw, i); } - if (vm && vm->batch_invalidate_tlb) + if (job->ring_ops_flush_tlb) i = emit_flush_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc), seqno, true, dw, i); dw[i++] = preparser_disable(false); - if (!vm || !vm->batch_invalidate_tlb) + if (!job->ring_ops_flush_tlb) i = emit_store_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc), seqno, dw, i); i = emit_bb_start(batch_addr, ppgtt_flag, dw, i); - if (job->user_fence.used) + if (job->user_fence.used) { + i = emit_flush_dw(dw, i); i = emit_store_imm_ppgtt_posted(job->user_fence.addr, job->user_fence.value, dw, i); + } i = emit_flush_imm_ggtt(xe_lrc_seqno_ggtt_addr(lrc), seqno, false, dw, i); @@ -325,7 +337,6 @@ struct xe_gt *gt = job->q->gt; struct xe_device *xe = gt_to_xe(gt); bool lacks_render = !(gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK); - struct xe_vm *vm = job->q->vm; u32 mask_flags = 0; dw[i++] = preparser_disable(true); @@ -335,7 +346,7 @@ mask_flags = PIPE_CONTROL_3D_ENGINE_FLAGS; /* See __xe_pt_bind_vma() for a discussion on TLB invalidations. */ - i = emit_pipe_invalidate(mask_flags, vm && vm->batch_invalidate_tlb, dw, i); + i = emit_pipe_invalidate(mask_flags, job->ring_ops_flush_tlb, dw, i); /* hsdes: 1809175790 */ if (has_aux_ccs(xe)) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_sched_job.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_sched_job.c @@ -250,6 +250,16 @@ void xe_sched_job_arm(struct xe_sched_job *job) { + struct xe_exec_queue *q = job->q; + struct xe_vm *vm = q->vm; + + if (vm && !xe_sched_job_is_migration(q) && !xe_vm_in_lr_mode(vm) && + (vm->batch_invalidate_tlb || vm->tlb_flush_seqno != q->tlb_flush_seqno)) { + xe_vm_assert_held(vm); + q->tlb_flush_seqno = vm->tlb_flush_seqno; + job->ring_ops_flush_tlb = true; + } + drm_sched_job_arm(&job->drm); } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_sched_job_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_sched_job_types.h @@ -39,6 +39,8 @@ } user_fence; /** @migrate_flush_flags: Additional flush flags for migration jobs */ u32 migrate_flush_flags; + /** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */ + bool ring_ops_flush_tlb; /** @batch_addr: batch buffer address of job */ u64 batch_addr[]; }; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_trace.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_trace.h @@ -468,7 +468,7 @@ TP_ARGS(vma) ); -DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate, +DEFINE_EVENT(xe_vma, xe_vma_invalidate, TP_PROTO(struct xe_vma *vma), TP_ARGS(vma) ); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c @@ -205,6 +205,11 @@ u64 stolen_size, io_size, pgsize; int err; + if (!mgr) { + drm_dbg_kms(&xe->drm, "Stolen mgr init failed\n"); + return; + } + if (IS_DGFX(xe)) stolen_size = detect_bar2_dgfx(xe, mgr); else if (GRAPHICS_VERx100(xe) >= 1270) --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c @@ -91,7 +91,7 @@ min_page_size = mgr->default_page_size; if (tbo->page_alignment) - min_page_size = tbo->page_alignment << PAGE_SHIFT; + min_page_size = (u64)tbo->page_alignment << PAGE_SHIFT; if (WARN_ON(min_page_size < mm->chunk_size)) { err = -EINVAL; --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_vm.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_vm.c @@ -520,7 +520,6 @@ { struct xe_vm *vm = container_of(w, struct xe_vm, preempt.rebind_work); struct drm_exec exec; - struct dma_fence *rebind_fence; unsigned int fence_count = 0; LIST_HEAD(preempt_fences); ktime_t end = 0; @@ -566,18 +565,11 @@ if (err) goto out_unlock; - rebind_fence = xe_vm_rebind(vm, true); - if (IS_ERR(rebind_fence)) { - err = PTR_ERR(rebind_fence); + err = xe_vm_rebind(vm, true); + if (err) goto out_unlock; - } - if (rebind_fence) { - dma_fence_wait(rebind_fence, false); - dma_fence_put(rebind_fence); - } - - /* Wait on munmap style VM unbinds */ + /* Wait on rebinds and munmap style VM unbinds */ wait = dma_resv_wait_timeout(xe_vm_resv(vm), DMA_RESV_USAGE_KERNEL, false, MAX_SCHEDULE_TIMEOUT); @@ -706,6 +698,7 @@ int err = 0; LIST_HEAD(tmp_evict); + xe_assert(vm->xe, !xe_vm_in_fault_mode(vm)); lockdep_assert_held_write(&vm->lock); /* Collect invalidated userptrs */ @@ -722,11 +715,27 @@ list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list, userptr.repin_link) { err = xe_vma_userptr_pin_pages(uvma); - if (err < 0) - return err; + if (err == -EFAULT) { + list_del_init(&uvma->userptr.repin_link); + + /* Wait for pending binds */ + xe_vm_lock(vm, false); + dma_resv_wait_timeout(xe_vm_resv(vm), + DMA_RESV_USAGE_BOOKKEEP, + false, MAX_SCHEDULE_TIMEOUT); + + err = xe_vm_invalidate_vma(&uvma->vma); + xe_vm_unlock(vm); + if (err) + return err; + } else { + if (err < 0) + return err; - list_del_init(&uvma->userptr.repin_link); - list_move_tail(&uvma->vma.combined_links.rebind, &vm->rebind_list); + list_del_init(&uvma->userptr.repin_link); + list_move_tail(&uvma->vma.combined_links.rebind, + &vm->rebind_list); + } } return 0; @@ -754,14 +763,14 @@ struct xe_sync_entry *syncs, u32 num_syncs, bool first_op, bool last_op); -struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker) +int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker) { - struct dma_fence *fence = NULL; + struct dma_fence *fence; struct xe_vma *vma, *next; lockdep_assert_held(&vm->lock); if (xe_vm_in_lr_mode(vm) && !rebind_worker) - return NULL; + return 0; xe_vm_assert_held(vm); list_for_each_entry_safe(vma, next, &vm->rebind_list, @@ -769,17 +778,17 @@ xe_assert(vm->xe, vma->tile_present); list_del_init(&vma->combined_links.rebind); - dma_fence_put(fence); if (rebind_worker) trace_xe_vma_rebind_worker(vma); else trace_xe_vma_rebind_exec(vma); fence = xe_vm_bind_vma(vma, NULL, NULL, 0, false, false); if (IS_ERR(fence)) - return fence; + return PTR_ERR(fence); + dma_fence_put(fence); } - return fence; + return 0; } static void xe_vma_free(struct xe_vma *vma) @@ -1558,7 +1567,6 @@ XE_WARN_ON(vm->pt_root[id]); trace_xe_vm_free(vm); - dma_fence_put(vm->rebind_fence); kfree(vm); } @@ -2010,7 +2018,7 @@ return err; } - if (vma->tile_mask != (vma->tile_present & ~vma->usm.tile_invalidated)) { + if (vma->tile_mask != (vma->tile_present & ~vma->tile_invalidated)) { return xe_vm_bind(vm, vma, q, xe_vma_bo(vma), syncs, num_syncs, true, first_op, last_op); } else { @@ -3184,9 +3192,8 @@ u8 id; int ret; - xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma))); xe_assert(xe, !xe_vma_is_null(vma)); - trace_xe_vma_usm_invalidate(vma); + trace_xe_vma_invalidate(vma); /* Check that we don't race with page-table updates */ if (IS_ENABLED(CONFIG_PROVE_LOCKING)) { @@ -3224,7 +3231,7 @@ } } - vma->usm.tile_invalidated = vma->tile_mask; + vma->tile_invalidated = vma->tile_mask; return 0; } --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_vm.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_vm.h @@ -207,7 +207,7 @@ int xe_vm_userptr_check_repin(struct xe_vm *vm); -struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker); +int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker); int xe_vm_invalidate_vma(struct xe_vma *vma); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xe/xe_vm_types.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xe/xe_vm_types.h @@ -83,11 +83,8 @@ struct work_struct destroy_work; }; - /** @usm: unified shared memory state */ - struct { - /** @tile_invalidated: VMA has been invalidated */ - u8 tile_invalidated; - } usm; + /** @tile_invalidated: VMA has been invalidated */ + u8 tile_invalidated; /** @tile_mask: Tile mask of where to create binding for this VMA */ u8 tile_mask; @@ -174,9 +171,6 @@ */ struct list_head rebind_list; - /** @rebind_fence: rebind fence from execbuf */ - struct dma_fence *rebind_fence; - /** * @destroy_work: worker to destroy VM, needed as a dma_fence signaling * from an irq context can be last put and the destroy needs to be able @@ -285,6 +279,11 @@ bool capture_once; } error_capture; + /** + * @tlb_flush_seqno: Required TLB flush seqno for the next exec. + * protected by the vm resv. + */ + u64 tlb_flush_seqno; /** @batch_invalidate_tlb: Always invalidate TLB before batch start */ bool batch_invalidate_tlb; /** @xef: XE file handle for tracking this VM's drm client */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/Kconfig +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/Kconfig @@ -5,13 +5,151 @@ depends on DMADEVICES depends on PHY_XILINX_ZYNQMP depends on XILINX_ZYNQMP_DPDMA + depends on DRM_XLNX + select VIDEOMODE_HELPERS + select XILINX_DMA_ENGINES select DMA_ENGINE select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HELPER select DRM_GEM_DMA_HELPER select DRM_KMS_HELPER select GENERIC_PHY + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_DP_HELPER + select MFD_SYSCON help This is a DRM/KMS driver for ZynqMP DisplayPort controller. Choose this option if you have a Xilinx ZynqMP SoC with DisplayPort subsystem. + +config DRM_XLNX + tristate "Xilinx DRM KMS Driver" + depends on DRM && OF + select DRM_KMS_HELPER + select DRM_KMS_DMA_HELPER + select DRM_GEM_DMA_HELPER + select SND_PCM_ELD + help + Xilinx DRM KMS driver. Choose this option if you have + a Xilinx SoCs with hardened display pipeline or soft + display pipeline using Xilinx IPs in FPGA. This module + provides the kernel mode setting functionalities + for Xilinx display drivers. + +config DRM_XLNX_BRIDGE + tristate "Xilinx DRM KMS bridge" + depends on DRM_XLNX + help + Xilinx DRM KMS bridge. This module provides some interfaces + to enable inter-module communication. Choose this option + from the provider driver when the Xilinx bridge interface is + needed. + +config DRM_XLNX_BRIDGE_DEBUG_FS + bool "Xilinx DRM KMS bridge debugfs" + depends on DEBUG_FS && DRM_XLNX_BRIDGE + help + Enable the debugfs code for Xilinx bridge. The debugfs code + enables debugging or testing related features. It exposes some + low level controls to the user space to help testing automation, + as well as can enable additional diagnostic or statistical + information. + +config DRM_XLNX_DPTX + tristate "Xilinx DRM DisplayPort Subsystem Driver" + depends on DRM_XLNX + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_HDMI_HELPER + select DRM_DISPLAY_DP_HELPER + select DRM_XLNX_HDCP + help + DRM driver for Xilinx DisplayPort Tx Subsystem for FPGA. Choose + this option if you have a FPGA display pipeline that includes + the Xilinx DisplayPort Tx Subsystem IP. The driver provides + the kernel mode setting functionalities for the IP. + +config DRM_XLNX_DSI + tristate "Xilinx DRM DSI Subsystem Driver" + depends on DRM_XLNX + select DRM_MIPI_DSI + select DRM_PANEL + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE + help + DRM driver for Xilinx MIPI-DSI. + +config DRM_XLNX_HDMITX + tristate "Xilinx DRM HDMI Subsystem Driver" + depends on DRM_XLNX + select DRM_XLNX_HDCP + help + DRM driver for Xilinx HDMI Tx Subsystem for FPGA. Choose + this option if you have a FPGA display pipeline that includes + the Xilinx HDMI Tx Subsystem IP. The driver provides + the kernel mode setting functionalities for the IP. + +config DRM_XLNX_MIXER + tristate "Xilinx DRM Mixer Driver" + depends on DRM_XLNX + select VIDEOMODE_HELPERS + help + DRM driver for Xilinx Mixer driver. + +config DRM_XLNX_PL_DISP + tristate "Xilinx DRM PL display driver" + depends on DRM_XLNX && XILINX_FRMBUF + select VIDEOMODE_HELPERS + help + DRM driver for Xilinx PL display driver, provides drm + crtc and plane object to display pipeline. You need to + choose this option if your display pipeline needs one + crtc and plane object with single DMA connected. + +config DRM_XLNX_SDI + tristate "Xilinx DRM SDI Subsystem Driver" + depends on DRM_XLNX + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_HDMI_HELPER + select DRM_DISPLAY_DP_HELPER + help + DRM driver for Xilinx SDI Tx Subsystem. + +config DRM_XLNX_BRIDGE_CSC + tristate "Xilinx DRM CSC Driver" + depends on DRM_XLNX_BRIDGE + help + DRM brige driver for color space converter of VPSS. Choose + this option if color space converter is connected to an encoder. + The driver provides set/get resolution and color format + functionality through bridge layer. + +config DRM_XLNX_BRIDGE_SCALER + tristate "Xilinx DRM Scaler Driver" + depends on DRM_XLNX_BRIDGE + help + DRM brige driver for scaler of VPSS. Choose this option + if scaler is connected to an encoder. The driver provides + upscaling, down scaling and no scaling functionality through + bridge layer. + +config DRM_XLNX_BRIDGE_VTC + tristate "Xilinx DRM VTC Driver" + depends on DRM_XLNX_BRIDGE + help + DRM brige driver for Xilinx Video Timing Controller. Choose + this option to make VTC a part of the CRTC in display pipeline. + Currently the support is added to the Xilinx Video Mixer and + Xilinx PL display CRTC drivers. This driver provides ability + to generate timings through the bridge layer. + +config DRM_XLNX_HDCP + bool "Xilinx DRM HDCP Driver" + depends on DRM_XLNX_DPTX || DRM_XLNX_HDMITX + select XILINX_HDCP_COMMON + select CRYPTO_AES + help + Enables the Functionality of HDCP Encryption/Decryption for + Xilinx display drivers. It handles the HDCP authentication. + Choose this option if you have a FPGA display pipeline using + Xilinx FPGA's in IP. This driver provides the kernel mode + setting functionalities for the IP. --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/Makefile @@ -1,2 +1,16 @@ -zynqmp-dpsub-y := zynqmp_disp.o zynqmp_dpsub.o zynqmp_dp.o zynqmp_kms.o +zynqmp-dpsub-y := zynqmp_disp.o zynqmp_dpsub.o zynqmp_dp.o obj-$(CONFIG_DRM_ZYNQMP_DPSUB) += zynqmp-dpsub.o +xlnx_drm-objs += xlnx_crtc.o xlnx_drv.o xlnx_fb.o xlnx_gem.o +xlnx_drm-$(CONFIG_DRM_XLNX_BRIDGE) += xlnx_bridge.o +obj-$(CONFIG_DRM_XLNX) += xlnx_drm.o +obj-$(CONFIG_DRM_XLNX_BRIDGE_CSC) += xlnx_csc.o +obj-$(CONFIG_DRM_XLNX_BRIDGE_SCALER) += xlnx_scaler.o +obj-$(CONFIG_DRM_XLNX_BRIDGE_VTC) += xlnx_vtc.o +obj-$(CONFIG_DRM_XLNX_DPTX) += xlnx_dptx.o +obj-$(CONFIG_DRM_XLNX_DSI) += xlnx_dsi.o +obj-$(CONFIG_DRM_XLNX_HDMITX) += xlnx_hdmi.o +obj-$(CONFIG_DRM_XLNX_MIXER) += xlnx_mixer.o +obj-$(CONFIG_DRM_XLNX_PL_DISP) += xlnx_pl_disp.o +xlnx-sdi-objs += xlnx_sdi.o xlnx_sdi_timing.o +obj-$(CONFIG_DRM_XLNX_SDI) += xlnx-sdi.o +obj-$(CONFIG_DRM_XLNX_HDCP) += hdcp/ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/Makefile +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_DRM_XLNX_HDCP) += xhdcp2x_tx.o \ + xhdcp1x_tx.o \ + xlnx_hdcp1x_keymngt.o \ + xlnx_hdcp1x_tx.o \ + xlnx_hdcp2x_tx.o \ + xlnx_hdcp_sha1.o \ + xlnx_hdcp2x_crypt.o xlnx_hdcp_tx.o --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xhdcp1x_tx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xhdcp1x_tx.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx HDCP1X Protocol Driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Katta Dhanunjanrao + * + * This driver provides standard HDCP1X protocol specific functionalites. + * It consists of: + * - A state machine which handles the states as specified in the HDCP + * specification. + * This driver still have Xilinx specific functionalities as it is not upstreamed now, + * it will be updated as more generic and standardized driver in the next upstream version. + * + * Reference : + * https://www.digital-cp.com/sites/default/files/specifications/HDCP%20on%20DisplayPort%20Specification%20Rev1_1.pdf + * + */ +#include +#include "xhdcp1x_tx.h" +#include "xlnx_hdcp1x_tx.h" + +static enum hdcp1x_tx_state hdcp1x_run_unautheticated_state(struct xlnx_hdcp1x_config *hdcp1x) +{ + hdcp1x->state_helper = 0; + return H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; +} + +static enum hdcp1x_tx_state hdcp1x_tx_runread_ksv_list_state_A7(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_tx_read_ksv_list(hdcp1x)) + return A4_HDCP1X_TX_STATE_AUTHENTICATED; + else + return REPTR_HDCP1X_TX_STATE_UNAUTHENTICATED; +} + +static enum hdcp1x_tx_state hdcp1x_tx_runwait_for_ready_state_A6(struct xlnx_hdcp1x_config *hdcp1x) +{ + return xlnx_hdcp1x_tx_wait_for_ready(hdcp1x); +} + +static enum hdcp1x_tx_state + hdcp1x_tx_run_testfor_repeater_state_A5(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_tx_test_for_repeater(hdcp1x)) { + xlnx_hdcp1x_tx_start_timer(hdcp1x, 100, 0); + return A6_HDCP1X_TX_STATE_WAIT_FOR_READY; + } + + return A4_HDCP1X_TX_STATE_AUTHENTICATED; +} + +static enum hdcp1x_tx_state hdcp1x_tx_run_authenticated_state_A4(struct xlnx_hdcp1x_config *hdcp1x) +{ + hdcp1x->state_helper = 0; + + if (hdcp1x->prev_state != A4_HDCP1X_TX_STATE_AUTHENTICATED) { + xlnx_hdcp1x_tx_start_timer(hdcp1x, 2000, 0); + hdcp1x->stats.auth_passed++; + + return A4_HDCP1X_TX_STATE_AUTHENTICATED; + } + if (hdcp1x->xhdcp1x_internal_timer.timer_expired) { + hdcp1x->xhdcp1x_internal_timer.timer_expired = 0; + xlnx_hdcp_tmrcntr_stop(&hdcp1x->xhdcp1x_internal_timer.tmr_ctr, 0); + xhdcp1x_tx_set_check_linkstate(hdcp1x, 1); + + return A4_HDCP1X_TX_STATE_AUTHENTICATED; + } + + if (hdcp1x->is_riupdate) { + xlnx_hdcp_tmrcntr_stop(&hdcp1x->xhdcp1x_internal_timer.tmr_ctr, 0); + + return A8_XHDCP1X_TX_STATE_LINK_INTEGRITY_CHECK; + } + + return A4_HDCP1X_TX_STATE_AUTHENTICATED; +} + +static enum hdcp1x_tx_state hdcp1x_tx_check_link_integrity(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_check_link_integrity(hdcp1x)) + return A4_HDCP1X_TX_STATE_AUTHENTICATED; + + return A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE; +} + +static enum hdcp1x_tx_state hdcp1x_tx_run_validaterx_state_A3(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_tx_validaterxstate(hdcp1x)) { + xlnx_hdcp1x_tx_enable_encryption(hdcp1x); + return A5_HDCP1X_TX_STATE_TEST_FOR_REPEATER; + } + + return H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; +} + +static enum hdcp1x_tx_state hdcp1x_tx_run_computations_state_A2(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_computationsstate(hdcp1x)) + return A3_HDCP1X_TX_STATE_VALIDATE_RX; + else + return A2_HDCP1X_TX_STATE_COMPUTATIONS; +} + +static enum hdcp1x_tx_state hdcp1x_tx_run_exchange_ksv_state_A1(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_exchangeksvs(hdcp1x)) + return A2_HDCP1X_TX_STATE_COMPUTATIONS; + else + return H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; +} + +static enum hdcp1x_tx_state + hdcp1x_tx_run_determine_rx_capable_state_A0(struct xlnx_hdcp1x_config *hdcp1x) +{ + if (xlnx_hdcp1x_tx_check_rxcapable(hdcp1x)) + return A1_HDCP1X_TX_STATE_EXCHANGE_KSVS; + else + return H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; +} + +static enum hdcp1x_tx_state hdcp1x_tx_run_disablestate(struct xlnx_hdcp1x_config *hdcp1x) +{ + hdcp1x->pending_events = 0; + + return A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE; +} + +/* + * HDCP Transmitter State Diagram available in + * HDCP1.1 specification. Section 2.3 + * https://www.digital-cp.com/sites/default/files/ + * specifications/HDCP%20on%20DisplayPort%20Specification%20Rev1_1.pdf + */ +int hdcp1x_tx_protocol_authenticate_sm(struct xlnx_hdcp1x_config *hdcp1x) +{ + int status = H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; + enum hdcp1x_tx_state hdcp1x_state = hdcp1x->curr_state; + + switch (hdcp1x_state) { + case H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED: + status = hdcp1x_tx_run_disablestate(hdcp1x); + break; + case A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE: + status = hdcp1x_tx_run_determine_rx_capable_state_A0(hdcp1x); + break; + case A1_HDCP1X_TX_STATE_EXCHANGE_KSVS: + status = hdcp1x_tx_run_exchange_ksv_state_A1(hdcp1x); + break; + case A2_HDCP1X_TX_STATE_COMPUTATIONS: + status = hdcp1x_tx_run_computations_state_A2(hdcp1x); + break; + case A3_HDCP1X_TX_STATE_VALIDATE_RX: + status = hdcp1x_tx_run_validaterx_state_A3(hdcp1x); + break; + case A4_HDCP1X_TX_STATE_AUTHENTICATED: + status = hdcp1x_tx_run_authenticated_state_A4(hdcp1x); + break; + case A8_XHDCP1X_TX_STATE_LINK_INTEGRITY_CHECK: + status = hdcp1x_tx_check_link_integrity(hdcp1x); + break; + case A5_HDCP1X_TX_STATE_TEST_FOR_REPEATER: + status = hdcp1x_tx_run_testfor_repeater_state_A5(hdcp1x); + break; + case A6_HDCP1X_TX_STATE_WAIT_FOR_READY: + status = hdcp1x_tx_runwait_for_ready_state_A6(hdcp1x); + break; + case A7_HDCP1X_TX_STATE_READ_KSV_LIST: + status = hdcp1x_tx_runread_ksv_list_state_A7(hdcp1x); + break; + case REPTR_HDCP1X_TX_STATE_UNAUTHENTICATED: + status = hdcp1x_run_unautheticated_state(hdcp1x); + break; + default: + status = hdcp1x_state; + dev_dbg(hdcp1x->dev, "Invalid HDCP1x State"); + break; + } + return status; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xhdcp1x_tx.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xhdcp1x_tx.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx HDCP1X Protocol Driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved + * . + * Author: katta Dhanunjanrao + * + */ +#ifndef HDCP1X_TX_H_ +#define HDCP1X_TX_H_ + +#include +#include +/* + * hdcp1x_tx_state: The enum structure has the HDCP state machine states. + * @H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED: HDCP state H0 + * @A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE: HDCP state A0 + * @A1_HDCP1X_TX_STATE_EXCHANGE_KSVS: HDCP state A1 + * @A2_HDCP1X_TX_STATE_COMPUTATIONS: HDCP state A2 + * @A3_HDCP1X_TX_STATE_VALIDATE_RX: HDCP state A3 + * @A4_HDCP1X_TX_STATE_AUTHENTICATED: HDCP state A4 + * @A5_HDCP1X_TX_STATE_TESTFORREPEATER: HDCP state A5 + * @REPTR_HDCP1X_TX_STATE_UNAUTHENTICATED: Repeater state checking + */ +enum hdcp1x_tx_state { + H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED = 0, + A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE, + A1_HDCP1X_TX_STATE_EXCHANGE_KSVS, + A2_HDCP1X_TX_STATE_COMPUTATIONS, + A3_HDCP1X_TX_STATE_VALIDATE_RX, + A4_HDCP1X_TX_STATE_AUTHENTICATED, + A8_XHDCP1X_TX_STATE_LINK_INTEGRITY_CHECK, + A5_HDCP1X_TX_STATE_TEST_FOR_REPEATER, + A6_HDCP1X_TX_STATE_WAIT_FOR_READY, + A7_HDCP1X_TX_STATE_READ_KSV_LIST, + REPTR_HDCP1X_TX_STATE_UNAUTHENTICATED +}; +#endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xhdcp2x_tx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xhdcp2x_tx.c @@ -0,0 +1,851 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx HDCP2X Protocol Driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + * + * This driver provides standard HDCP2X protocol specific functionalites. + * It consists of: + * - A state machine which handles the states as specified in the HDCP + * specification. + * This driver still have Xilinx specific functionalities as it is not upstreamed now, + * it will be updated as more generic and standardized driver in the next upstream version. + * + * Reference : + * https://www.digital-cp.com/sites/default/files/HDCP%20on%20DisplayPort%20Specification%20Rev2_3.pdf + */ + +#include +#include +#include +#include +#include "xhdcp2x_tx.h" +#include "xlnx_hdcp2x_tx.h" + +static int hdcp2x_tx_receive_message(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 msg_id) +{ + return xlnx_hdcp2x_tx_read_msg(xhdcp2x_tx, msg_id); +} + +static enum hdcp2x_tx_state hdcp2x_tx_verify_mprime(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + int result; + + /* + * Wait for the receiver to respond within 100 msecs. + * If the receiver has timed out we go to state A9 for a retry. + * If the receiver is busy, we stay in this state (return from polling). + * If the receiver has finished, but the message was not handled yet, + * we handle the message. + */ + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, + HDCP2X_TX_REPEATERAUTH_STREAM_READY_SIZE, + 0); + if (result < 0) + return A9_HDCP2X_TX_STREAM_MANAGE; + + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A9_HDCP2X_TX_VERIFY_MPRIME; + + if (xhdcp2x_tx->xhdcp2x_info.content_strm_mng_chk_cntr) + dev_dbg(xhdcp2x_tx->dev, "content stream manage message"); + + result = hdcp2x_tx_receive_message(xhdcp2x_tx, + HDCP_2_2_REP_STREAM_READY); + if (result < 0) + return A9_HDCP2X_TX_STREAM_MANAGE; + + if (memcmp(tx_msg->msg_type.rpt_auth_stream_rdy.m_prime, + xhdcp2x_tx->xhdcp2x_info.M, + HDCP_2_2_MPRIME_LEN)) + return A9_HDCP2X_TX_STREAM_MANAGE; + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP2X_TX_WAIT_FOR_ENCRYPTION_TIMEOUT, + XHDCP2X_TX_TS_WAIT_FOR_CIPHER); + + xhdcp2x_tx->xhdcp2x_info.is_content_stream_type_set = 1; + + return A5_HDCP2X_TX_AUTHENTICATED; +} + +static enum hdcp2x_tx_state hdcp2x_tx_process_stream_manage(struct xlnx_hdcp2x_config + *xhdcp2x_tx) +{ + struct xhdcp2x_tx_internal_info *hdcp2x_tx_internal_info = + &xhdcp2x_tx->xhdcp2x_info; + int result; + + if (!xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired) + return A9_HDCP2X_TX_STREAM_MANAGE; + + xlnx_hdcp2x_tx_read_rxstatus(xhdcp2x_tx); + if ((hdcp2x_tx_internal_info->dp_rx_status & + XHDCP2X_TX_RXSTATUS_REAUTH_REQ_MASK) == + XHDCP2X_TX_RXSTATUS_REAUTH_REQ_MASK) { + xlnx_hdcp2x_handle_reauth_request(xhdcp2x_tx); + return A0_HDCP2X_TX_AKE_INIT; + } + + if (!hdcp2x_tx_internal_info->is_content_stream_type_set) { + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP2X_TX_WAIT_FOR_STREAM_TYPE_TIMEOUT, + XHDCP2X_TX_TS_WAIT_FOR_STREAM_TYPE); + return A9_HDCP2X_TX_STREAM_MANAGE; + } + + if (!hdcp2x_tx_internal_info->content_strm_mng_chk_cntr) + dev_dbg(xhdcp2x_tx->dev, "verify receiver-id"); + + if (hdcp2x_tx_internal_info->content_strm_mng_chk_cntr >= + XHDCP2X_TX_MAX_ALLOWED_STREAM_MANAGE_CHECKS) { + dev_err(xhdcp2x_tx->dev, + "content stream manage check counter fail"); + return A0_HDCP2X_TX_AKE_INIT; + } + + if (hdcp2x_tx_internal_info->seq_num_m < + hdcp2x_tx_internal_info->prev_seq_num_m) { + return A0_HDCP2X_TX_AKE_INIT; + } + + hdcp2x_tx_internal_info->prev_seq_num_m = hdcp2x_tx_internal_info->seq_num_m; + + result = xlnx_hdcp2x_tx_rptr_auth_stream_mng(xhdcp2x_tx); + if (result < 0) { + dev_dbg(xhdcp2x_tx->dev, "write message fail: stream manage"); + return A0_HDCP2X_TX_AKE_INIT; + } + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_STREAM_READY_TIMEOUT_MS, + HDCP_2_2_REP_STREAM_READY); + + hdcp2x_tx_internal_info->content_strm_mng_chk_cntr++; + + return A9_HDCP2X_TX_VERIFY_MPRIME; +} + +static enum hdcp2x_tx_state hdcp2x_tx_process_rcvid(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + dev_dbg(xhdcp2x_tx->dev, "receiver id sent ack"); + + return A0_HDCP2X_TX_AKE_INIT; +} + +static enum hdcp2x_tx_state hdcp2x_tx_wait_for_rcvid(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info = + (struct hdcp2x_tx_pairing_info *)xhdcp2x_tx->xhdcp2x_info.state_context; + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + u8 V[HDCP2X_TX_V_SIZE]; + u32 seq_num_v; + int i, result; + u8 device_count; + + /* + * Wait for the receiver to respond within 3 secs. + * If the receiver has timed out we go to state A0. + * If the receiver is busy, we stay in this state (return from polling). + * If the receiver has finished, but the message was not handled yet, + * we handle the message. + */ + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, 0, 1); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A6_HDCP2X_TX_WAIT_FOR_RCVID; + + dev_dbg(xhdcp2x_tx->dev, "wait for receiver id"); + + result = hdcp2x_tx_receive_message(xhdcp2x_tx, + HDCP_2_2_REP_SEND_RECVID_LIST); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + device_count = (HDCP_2_2_DEV_COUNT_HI(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[0]) << 4 | + HDCP_2_2_DEV_COUNT_LO(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[1])); + + xhdcp2x_tx->xhdcp2x_topology.devicecount = device_count + 1; + xhdcp2x_tx->xhdcp2x_topology.depth = + HDCP_2_2_DEPTH(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[0]); + xhdcp2x_tx->xhdcp2x_topology.max_dev_exceeded = + HDCP_2_2_MAX_DEVS_EXCEEDED(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[1]); + xhdcp2x_tx->xhdcp2x_topology.max_cascaded_exceeded = + HDCP_2_2_MAX_CASCADE_EXCEEDED(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[1]); + xhdcp2x_tx->xhdcp2x_topology.hdcp2x_legacy_ds = + HDCP2X_TX_LEGACY2X_DEVICE_DOWNSTREAM(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[1]); + xhdcp2x_tx->xhdcp2x_topology.hdcp1x_legacy_ds = + HDCP2X_TX_LEGACY1X_DEVICE_DOWNSTREAM(tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo[1]); + + if (xhdcp2x_tx->xhdcp2x_topology.max_dev_exceeded || + xhdcp2x_tx->xhdcp2x_topology.max_cascaded_exceeded) { + dev_err(xhdcp2x_tx->dev, "Failed with topology errors"); + return A0_HDCP2X_TX_AKE_INIT; + } + + dev_dbg(xhdcp2x_tx->dev, "start compute V-hash"); + + xlnx_hdcp2x_tx_compute_v(xhdcp2x_tx->xhdcp2x_info.rn, + xhdcp2x_tx->xhdcp2x_info.r_rx, + tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo, + xhdcp2x_tx->xhdcp2x_info.r_tx, + (u8 *)tx_msg->msg_type.rpt_auth_send_rcvid.rcvids, + device_count, + tx_msg->msg_type.rpt_auth_send_rcvid.seq_num_v, + hdcp2x_tx_pairing_info->km, V); + + dev_dbg(xhdcp2x_tx->dev, "start compute V-hash done"); + + if (memcmp(tx_msg->msg_type.rpt_auth_send_rcvid.vprime, V, + HDCP_2_2_V_PRIME_HALF_LEN)) { + dev_err(xhdcp2x_tx->dev, "v-prime compare fail"); + return A0_HDCP2X_TX_AKE_INIT; + } + + for (i = 0; i < device_count; i++) { + memcpy(&xhdcp2x_tx->xhdcp2x_topology.rcvid[i + 1], + &tx_msg->msg_type.rpt_auth_send_rcvid.rcvids[i], + HDCP_2_2_RECEIVER_ID_LEN); + if (xhdcp2x_tx->xhdcp2x_hw.tx_mode == XHDCP2X_TX_TRANSMITTER) { + u8 *rcv_id = tx_msg->msg_type.rpt_auth_send_rcvid.rcvids[i]; + + if (xlnx_hdcp2x_tx_is_device_revoked(xhdcp2x_tx, rcv_id)) { + xhdcp2x_tx->xhdcp2x_info.is_device_revoked = 1; + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_DEVICE_IS_REVOKED; + return A0_HDCP2X_TX_AKE_INIT; + } + } + } + + seq_num_v = drm_hdcp_be24_to_cpu(tx_msg->msg_type.rpt_auth_send_rcvid.seq_num_v); + if (seq_num_v < xhdcp2x_tx->xhdcp2x_info.seq_num_v) + return A0_HDCP2X_TX_AKE_INIT; + + xhdcp2x_tx->xhdcp2x_info.seq_num_v = seq_num_v; + + result = xlnx_hdcp2x_tx_write_rptr_auth_send_ack(xhdcp2x_tx, + &V[HDCP_2_2_V_PRIME_HALF_LEN]); + if (result < 0) { + dev_err(xhdcp2x_tx->dev, "write message fail - V prime"); + return A0_HDCP2X_TX_AKE_INIT; + } + + return A9_HDCP2X_TX_STREAM_MANAGE; +} + +static enum hdcp2x_tx_state hdcp2x_tx_authenticated(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + if (!xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired) + return A5_HDCP2X_TX_AUTHENTICATED; + + if (xhdcp2x_tx->xhdcp2x_info.auth_status + != XHDCP2X_TX_AUTHENTICATED) + dev_dbg(xhdcp2x_tx->dev, "HDCP 2X Authenticated"); + + if (xhdcp2x_tx->xhdcp2x_internal_timer.reason_id == + XHDCP2X_TX_TS_WAIT_FOR_CIPHER) { + u8 handle_reauth_request = 0; + + if (xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_DP) { + if ((xhdcp2x_tx->xhdcp2x_info.dp_rx_status & + (XHDCP2X_RX_STATUS_REAUTH_REQ | + XHDCP2X_RX_STATUS_LINK_INTEGRITY_FAIL))) { + xhdcp2x_tx->xhdcp2x_info.dp_rx_status &= + ~(XHDCP2X_RX_STATUS_REAUTH_REQ | + XHDCP2X_RX_STATUS_LINK_INTEGRITY_FAIL); + handle_reauth_request = 1; + } + } else { + if (xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_REAUTH_REQ_MASK) + handle_reauth_request = 1; + } + + if (handle_reauth_request) { + xlnx_hdcp2x_handle_reauth_request(xhdcp2x_tx); + return A0_HDCP2X_TX_AKE_INIT; + } + + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_AUTHENTICATED; + + xlnx_hdcp2x_tx_enable_encryption(xhdcp2x_tx); + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP2X_TX_WAIT_REAUTH_CHECK_TIMEOUT, + XHDCP2X_TX_TS_RX_REAUTH_CHECK); + + dev_info(xhdcp2x_tx->dev, "HDCP 2X Authenticated"); + + return A5_HDCP2X_TX_AUTHENTICATED; + } + + if (xhdcp2x_tx->xhdcp2x_internal_timer.reason_id == + XHDCP2X_TX_TS_RX_REAUTH_CHECK) { + u8 handle_reauth_request = 0; + u8 handle_repeater_rdy = 0; + + dev_dbg(xhdcp2x_tx->dev, "check for re-authentication"); + + if (xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_DP) { + if ((xhdcp2x_tx->xhdcp2x_info.dp_rx_status & + (XHDCP2X_RX_STATUS_REAUTH_REQ | + XHDCP2X_RX_STATUS_LINK_INTEGRITY_FAIL))) { + xhdcp2x_tx->xhdcp2x_info.dp_rx_status &= + ~(XHDCP2X_RX_STATUS_REAUTH_REQ | + XHDCP2X_RX_STATUS_LINK_INTEGRITY_FAIL); + handle_reauth_request = 1; + } + + if ((xhdcp2x_tx->xhdcp2x_info.dp_rx_status & + XHDCP2X_RX_STATUS_RPTR_RDY) == + XHDCP2X_RX_STATUS_RPTR_RDY) + handle_repeater_rdy = 1; + } else { + if (xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_REAUTH_REQ_MASK) + handle_reauth_request = 1; + + if (xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_READY_MASK) + handle_repeater_rdy = 1; + } + + if (handle_reauth_request) { + xlnx_hdcp2x_handle_reauth_request(xhdcp2x_tx); + return A0_HDCP2X_TX_AKE_INIT; + } + if (handle_repeater_rdy) { + /* The downstream topology has changed */ + return A6_HDCP2X_TX_WAIT_FOR_RCVID; + } + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP2X_TX_WAIT_REAUTH_CHECK_TIMEOUT, + XHDCP2X_TX_TS_RX_REAUTH_CHECK); + } + + return A5_HDCP2X_TX_AUTHENTICATED; +} + +static enum hdcp2x_tx_state hdcp2x_tx_rptr_check(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + if (xhdcp2x_tx->xhdcp2x_info.is_rcvr_repeater) { + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_RECVID_LIST_TIMEOUT_MS, + HDCP_2_2_REP_SEND_RECVID_LIST); + return A6_HDCP2X_TX_WAIT_FOR_RCVID; + } + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP2X_TX_WAIT_FOR_ENCRYPTION_TIMEOUT, + XHDCP2X_TX_TS_WAIT_FOR_CIPHER); + + return A5_HDCP2X_TX_AUTHENTICATED; +} + +static enum hdcp2x_tx_state hdcp2x_tx_exchange_ks(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info = (struct hdcp2x_tx_pairing_info *) + xhdcp2x_tx->xhdcp2x_info.state_context; + u8 riv[HDCP_2_2_RIV_LEN]; + u8 ks[HDCP2X_TX_KS_SIZE]; + u8 edkeys_ks[HDCP_2_2_E_DKEY_KS_LEN]; + int result; + + dev_dbg(xhdcp2x_tx->dev, "tx exchange ks"); + + xlnx_hdcp2x_rng_get_random_number(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng, + riv, HDCP_2_2_RIV_LEN, HDCP_2_2_RIV_LEN); + xlnx_hdcp2x_cipher_set_keys(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher, + riv, XHDCP2X_CIPHER_REG_RIV_1_OFFSET, HDCP_2_2_RIV_LEN); + xlnx_hdcp2x_rng_get_random_number(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng, ks, + HDCP2X_TX_KS_SIZE, + HDCP2X_TX_KS_SIZE); + xlnx_hdcp2x_cipher_set_keys(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher, + ks, XHDCP2X_CIPHER_REG_KS_1_OFFSET, HDCP2X_TX_KS_SIZE); + xlnx_hdcp2x_tx_compute_edkey_ks(xhdcp2x_tx->xhdcp2x_info.rn, + hdcp2x_tx_pairing_info->km, ks, + xhdcp2x_tx->xhdcp2x_info.r_rx, + xhdcp2x_tx->xhdcp2x_info.r_tx, + edkeys_ks); + + result = xlnx_hdcp2x_tx_write_ske_send_eks(xhdcp2x_tx, edkeys_ks, riv); + if (result < 0) { + dev_err(xhdcp2x_tx->dev, "ske send eks write fail"); + return A0_HDCP2X_TX_AKE_INIT; + } + + result = xlnx_hdcp2x_tx_write_type_value(xhdcp2x_tx); + if (result < 0) { + dev_err(xhdcp2x_tx->dev, "SKE send ES write fail"); + return A0_HDCP2X_TX_AKE_INIT; + } + + return A4_HDCP2X_TX_REPEATER_CHECK; +} + +static enum hdcp2x_tx_state hdcp2x_tx_verify_lprime_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info = + (struct hdcp2x_tx_pairing_info *)xhdcp2x_tx->xhdcp2x_info.state_context; + u8 lprime[HDCP_2_2_L_PRIME_LEN]; + int result = 0; + + /* + * Wait for the receiver to respond within 20 msecs. + * If the receiver has timed out we go to state A2 for a retry. + * If the receiver is busy, we stay in this state (return from polling). + * If the receiver has finished, but the message was not handled yet, + * we handle the message. + */ + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, + sizeof(struct hdcp2x_tx_lc_send_lc_prime), + 0); + if (result < 0) + return A2_HDCP2X_TX_LC_CHECK; + + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A2_HDCP2X_TX_VERIFY_LPRIME; + + result = hdcp2x_tx_receive_message(xhdcp2x_tx, HDCP_2_2_LC_SEND_LPRIME); + if (result < 0) + return A2_HDCP2X_TX_LC_CHECK; + + xlnx_hdcp2x_tx_compute_lprime(xhdcp2x_tx->xhdcp2x_info.rn, + hdcp2x_tx_pairing_info->km, + xhdcp2x_tx->xhdcp2x_info.r_rx, + xhdcp2x_tx->xhdcp2x_info.r_tx, + lprime); + + if (memcmp(tx_msg->msg_type.lcsend_lcprime.lprime, + lprime, sizeof(lprime))) { + dev_err(xhdcp2x_tx->dev, "compare L fail"); + return A2_HDCP2X_TX_LC_CHECK; + } + + dev_dbg(xhdcp2x_tx->dev, "locality check counter=%d\n", + (u16)xhdcp2x_tx->xhdcp2x_info.lc_counter); + + return A3_HDCP2X_TX_EXCHANGE_KS; +} + +static enum hdcp2x_tx_state hdcp2x_tx_lc_check(struct xlnx_hdcp2x_config + *xhdcp2x_tx) +{ + int result; + + xhdcp2x_tx->xhdcp2x_info.lc_counter++; + + if (xhdcp2x_tx->xhdcp2x_info.lc_counter > + HDCP2X_TX_MAX_ALLOWED_LOCALITY_CHECKS) { + dev_dbg(xhdcp2x_tx->dev, "lc_counter = %d/n", + (u16)xhdcp2x_tx->xhdcp2x_info.lc_counter - 1); + return A0_HDCP2X_TX_AKE_INIT; + } + + xlnx_hdcp2x_rng_get_random_number(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng, + xhdcp2x_tx->xhdcp2x_info.rn, + HDCP_2_2_RN_LEN, + HDCP_2_2_RN_LEN); + result = xlnx_hdcp2x_tx_write_lcinit(xhdcp2x_tx, + xhdcp2x_tx->xhdcp2x_info.rn); + if (result < 0) { + dev_err(xhdcp2x_tx->dev, "write lc-init message fail"); + return A0_HDCP2X_TX_AKE_INIT; + } + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_DP_LPRIME_TIMEOUT_MS, + HDCP_2_2_LC_SEND_LPRIME); + + return A2_HDCP2X_TX_VERIFY_LPRIME; +} + +static enum hdcp2x_tx_state hdcp2x_tx_compute_hprime(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info = + (struct hdcp2x_tx_pairing_info *)xhdcp2x_tx->xhdcp2x_info.state_context; + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + u8 h_prime[HDCP_2_2_H_PRIME_LEN]; + int result = 0; + + /* + * Wait for the receiver to respond within 1 second. + * If the receiver has timed out we go to state A0. + * If the receiver is busy, we stay in this state (return from polling). + * If the receiver has finished, but the message was not handled yet, + * we handle the message. + */ + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, + sizeof(struct hdcp2x_tx_ake_sendprime), + 0); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A1_HDCP2X_TX_VERIFY_HPRIME; + + result = hdcp2x_tx_receive_message(xhdcp2x_tx, HDCP_2_2_AKE_SEND_HPRIME); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + xlnx_hdcp2x_tx_compute_hprime(xhdcp2x_tx->xhdcp2x_info.r_rx, + hdcp2x_tx_pairing_info->rxcaps, + xhdcp2x_tx->xhdcp2x_info.r_tx, + xhdcp2x_tx->xhdcp2x_info.txcaps, + hdcp2x_tx_pairing_info->km, h_prime); + + if (memcmp(tx_msg->msg_type.ake_send_prime.h_prime, h_prime, + sizeof(h_prime))) { + dev_err(xhdcp2x_tx->dev, "compare H' fail"); + xlnx_hdcp2x_tx_invalidate_paring_info(xhdcp2x_tx, + hdcp2x_tx_pairing_info->rcvid); + return A0_HDCP2X_TX_AKE_INIT; + } + + return A2_HDCP2X_TX_LC_CHECK; +} + +static enum hdcp2x_tx_state hdcp2x_tx_wait_for_pairing_info(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info = &xhdcp2x_tx->xhdcp2x_pairing_info; + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + int result = 0; + + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, + sizeof(struct hdcp2x_tx_ake_send_pairing_info), + 0); + if (result < 0) { + xlnx_hdcp2x_tx_invalidate_paring_info(xhdcp2x_tx, hdcp2x_tx_pairing_info->rcvid); + return A0_HDCP2X_TX_AKE_INIT; + } + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A1_HDCP2X_TX_WAIT_FOR_PAIRING; + + dev_dbg(xhdcp2x_tx->dev, "wait for pairing to be done"); + result = hdcp2x_tx_receive_message(xhdcp2x_tx, + HDCP_2_2_AKE_SEND_PAIRING_INFO); + if (result < 0) { + xlnx_hdcp2x_tx_invalidate_paring_info(xhdcp2x_tx, hdcp2x_tx_pairing_info->rcvid); + return A0_HDCP2X_TX_AKE_INIT; + } + + memcpy(hdcp2x_tx_pairing_info->ekh_km, + tx_msg->msg_type.ake_send_pairing_info.ekh_km, + sizeof(hdcp2x_tx_pairing_info->ekh_km)); + + hdcp2x_tx_pairing_info = xlnx_hdcp2x_tx_update_pairinginfo(xhdcp2x_tx, + hdcp2x_tx_pairing_info, 1); + + return A2_HDCP2X_TX_LC_CHECK; +} + +static enum hdcp2x_tx_state hdcp2x_tx_wait_for_hprime_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info = + (struct hdcp2x_tx_pairing_info *) + xhdcp2x_tx->xhdcp2x_info.state_context; + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + u8 h_prime[HDCP_2_2_H_PRIME_LEN]; + int result = 0; + + /* + * Wait for the receiver to respond within 1 second. + * If the receiver has timed out we go to state A0. + * If the receiver is busy, we stay in this state (return from polling). + * If the receiver has finished, but the message was not handled yet, + * we handle the message. + */ + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, + sizeof(struct hdcp2x_tx_ake_sendprime), 0); + if (result < 0) { + xlnx_hdcp2x_tx_invalidate_paring_info(xhdcp2x_tx, + hdcp2x_tx_pairing_info->rcvid); + return A0_HDCP2X_TX_AKE_INIT; + } + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A1_HDCP2X_TX_WAIT_FOR_HPRIME; + + dev_dbg(xhdcp2x_tx->dev, "wait for H-Prime"); + + result = hdcp2x_tx_receive_message(xhdcp2x_tx, + HDCP_2_2_AKE_SEND_HPRIME); + if (result < 0) { + xlnx_hdcp2x_tx_invalidate_paring_info(xhdcp2x_tx, + hdcp2x_tx_pairing_info->rcvid); + return A0_HDCP2X_TX_AKE_INIT; + } + + xlnx_hdcp2x_tx_compute_hprime(hdcp2x_tx_pairing_info->rrx, + hdcp2x_tx_pairing_info->rxcaps, + hdcp2x_tx_pairing_info->rtx, + xhdcp2x_tx->xhdcp2x_info.txcaps, + hdcp2x_tx_pairing_info->km, h_prime); + dev_dbg(xhdcp2x_tx->dev, "Compute H' done"); + + if (memcmp(tx_msg->msg_type.ake_send_prime.h_prime, h_prime, sizeof(h_prime))) { + dev_dbg(xhdcp2x_tx->dev, "compare H' fail"); + + xlnx_hdcp2x_tx_invalidate_paring_info(xhdcp2x_tx, + hdcp2x_tx_pairing_info->rcvid); + return A0_HDCP2X_TX_AKE_INIT; + } + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_PAIRING_TIMEOUT_MS, + HDCP_2_2_AKE_SEND_PAIRING_INFO); + + return A1_HDCP2X_TX_WAIT_FOR_PAIRING; +} + +static enum hdcp2x_tx_state hdcp2x_tx_wait_for_ack(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg *xhdcp2x_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + struct hdcp2x_tx_pairing_info *xhdcp2x_pairing_info = NULL; + struct hdcp2x_tx_pairing_info xhdcp2x_new_pairing_info; + const u8 *kpubdpcptr = NULL; + int result; + + result = xlnx_hdcp2x_tx_wait_for_receiver(xhdcp2x_tx, + sizeof(struct hdcp2x_tx_ake_sendcert), 0); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + if (!xhdcp2x_tx->xhdcp2x_info.msg_available) + return A1_HDCP2X_TX_WAIT_FOR_ACK; + + result = hdcp2x_tx_receive_message(xhdcp2x_tx, HDCP_2_2_AKE_SEND_CERT); + + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + kpubdpcptr = xlnx_hdcp2x_tx_get_publickey(xhdcp2x_tx); + + if (!kpubdpcptr) + return A0_HDCP2X_TX_AKE_INIT; + + result = xlnx_hdcp2x_tx_verify_certificate(&xhdcp2x_msg->msg_type.ake_send_cert.cert_rx, + kpubdpcptr, HDCP2X_TX_KPUB_DCP_LLC_N_SIZE, + &kpubdpcptr[HDCP2X_TX_KPUB_DCP_LLC_N_SIZE], + HDCP2X_TX_KPUB_DCP_LLC_E_SIZE); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + if (xhdcp2x_tx->xhdcp2x_hw.tx_mode == XHDCP2X_TX_TRANSMITTER) { + u8 *rcv_id = xhdcp2x_msg->msg_type.ake_send_cert.cert_rx.rcvid; + + if (xlnx_hdcp2x_tx_is_device_revoked(xhdcp2x_tx, rcv_id)) { + xhdcp2x_tx->xhdcp2x_info.is_device_revoked = 1; + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_DEVICE_IS_REVOKED; + return A0_HDCP2X_TX_AKE_INIT; + } + xhdcp2x_tx->xhdcp2x_info.is_device_revoked = 0; + } + memcpy(&xhdcp2x_tx->xhdcp2x_topology.rcvid[0], + xhdcp2x_msg->msg_type.ake_send_cert.cert_rx.rcvid, + HDCP_2_2_RECEIVER_ID_LEN); + xhdcp2x_tx->xhdcp2x_topology.devicecount = 1; + + if (xhdcp2x_msg->msg_type.ake_send_cert.rxcaps[2] & 0x1) + xhdcp2x_tx->xhdcp2x_info.is_rcvr_repeater = 1; + else + xhdcp2x_tx->xhdcp2x_info.is_rcvr_repeater = 0; + + memcpy(xhdcp2x_tx->xhdcp2x_info.r_rx, + xhdcp2x_msg->msg_type.ake_send_cert.r_rx, + sizeof(xhdcp2x_tx->xhdcp2x_info.r_rx)); + + xhdcp2x_pairing_info = + xlnx_hdcp2x_tx_get_pairing_info(xhdcp2x_tx, + xhdcp2x_msg->msg_type.ake_send_cert.cert_rx.rcvid); + if (xhdcp2x_pairing_info) { + if (xhdcp2x_pairing_info->ready) { + memcpy(xhdcp2x_pairing_info->rxcaps, + xhdcp2x_msg->msg_type.ake_send_cert.rxcaps, + sizeof(xhdcp2x_pairing_info->rxcaps)); + + result = xlnx_hdcp2x_tx_write_ake_storedkm(xhdcp2x_tx, + xhdcp2x_pairing_info); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + xhdcp2x_tx->xhdcp2x_info.state_context = + xhdcp2x_pairing_info; + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_PAIRING_TIMEOUT_MS, + HDCP_2_2_AKE_SEND_HPRIME); + return A1_HDCP2X_TX_VERIFY_HPRIME; + } + } + memcpy(xhdcp2x_new_pairing_info.rrx, xhdcp2x_tx->xhdcp2x_info.r_rx, + sizeof(xhdcp2x_new_pairing_info.rrx)); + memcpy(xhdcp2x_new_pairing_info.rtx, xhdcp2x_tx->xhdcp2x_info.r_tx, + sizeof(xhdcp2x_new_pairing_info.rtx)); + memcpy(xhdcp2x_new_pairing_info.rxcaps, xhdcp2x_msg->msg_type.ake_send_cert.rxcaps, + sizeof(xhdcp2x_new_pairing_info.rxcaps)); + memcpy(xhdcp2x_new_pairing_info.rcvid, xhdcp2x_msg->msg_type.ake_send_cert.cert_rx.rcvid, + sizeof(xhdcp2x_new_pairing_info.rcvid)); + + xlnx_hdcp2x_tx_generatekm(xhdcp2x_tx, xhdcp2x_new_pairing_info.km); + + xhdcp2x_pairing_info = + xlnx_hdcp2x_tx_update_pairinginfo(xhdcp2x_tx, + &xhdcp2x_new_pairing_info, + 0); + if (!xhdcp2x_pairing_info) + return A0_HDCP2X_TX_AKE_INIT; + + xhdcp2x_tx->xhdcp2x_info.state_context = (void *)xhdcp2x_pairing_info; + + result = xlnx_hdcp2x_tx_write_akenostored_km(xhdcp2x_tx, + &xhdcp2x_new_pairing_info, + &xhdcp2x_msg->msg_type.ake_send_cert.cert_rx); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS, + HDCP_2_2_AKE_SEND_HPRIME); + + return A1_HDCP2X_TX_WAIT_FOR_HPRIME; +} + +static enum hdcp2x_tx_state hdcp2x_tx_write_ake_init(struct xlnx_hdcp2x_config + *xhdcp2x_tx) +{ + if (!xhdcp2x_tx->xhdcp2x_info.is_enabled) + return H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE; + + if (!xhdcp2x_tx->xhdcp2x_info.is_rcvr_hdcp2x_capable) { + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_INCOMPATIBLE_RX; + return H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE; + } + + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_AUTHENTICATION_BUSY; + + xlnx_hdcp2x_tx_disable_encryption(xhdcp2x_tx); + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_CERT_TIMEOUT_MS, A0_HDCP2X_TX_AKE_INIT); + + return A1_HDCP2X_TX_EXCHANGE_KM; +} + +static enum hdcp2x_tx_state hdcp2x_tx_exchange_km_process(struct xlnx_hdcp2x_config + *xhdcp2x_tx) +{ + int result; + + if (!xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired) + return A1_HDCP2X_TX_EXCHANGE_KM; + + result = xlnx_hdcp2x_tx_write_ake_init(xhdcp2x_tx); + if (result < 0) + return A0_HDCP2X_TX_AKE_INIT; + + xlnx_hdcp2x_tx_start_timer(xhdcp2x_tx, HDCP_2_2_CERT_TIMEOUT_MS, HDCP_2_2_AKE_SEND_CERT); + + memset(&xhdcp2x_tx->xhdcp2x_topology, 0, sizeof(xhdcp2x_tx->xhdcp2x_topology)); + + xhdcp2x_tx->xhdcp2x_info.seq_num_v = 0; + xhdcp2x_tx->xhdcp2x_info.seq_num_m = 0; + xhdcp2x_tx->xhdcp2x_info.content_strm_mng_chk_cntr = 0; + xhdcp2x_tx->xhdcp2x_info.lc_counter = 0; + xhdcp2x_tx->xhdcp2x_info.prev_seq_num_m = 0; + + return A1_HDCP2X_TX_WAIT_FOR_ACK; +} + +static enum hdcp2x_tx_state hdcp2x_tx_wait_for_tx_state(struct xlnx_hdcp2x_config + *xhdcp2x_tx) +{ + if (xhdcp2x_tx->xhdcp2x_info.auth_status != + XHDCP2X_TX_AUTHENTICATION_BUSY) + return H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE; + + xhdcp2x_tx->xhdcp2x_info.is_rcvr_hdcp2x_capable = + xlnx_hdcp2x_downstream_capbility(xhdcp2x_tx); + + if (xhdcp2x_tx->xhdcp2x_info.is_rcvr_hdcp2x_capable) + return A0_HDCP2X_TX_AKE_INIT; + + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_INCOMPATIBLE_RX; + + return H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE; +} + +static enum hdcp2x_tx_state hdcp2x_tx_idle_state(struct xlnx_hdcp2x_config + *xhdcp2x_tx) +{ + return H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE; +} + +/* + * HDCP Transmitter State Diagram available in + * HDCP2.3 specification. Section 2.8 + * https://www.digital-cp.com/sites/default/files/ + * HDCP%20Interface%20Independent%20Adaptation%20Specification%20Rev2_3.pdf + */ +int hdcp2x_tx_protocol_authenticate_sm(struct xlnx_hdcp2x_config *hdcp2x_tx) +{ + int status = H0_HDCP2X_TX_NO_RX_ATTACHED; + enum hdcp2x_tx_state hdcp_state = hdcp2x_tx->xhdcp2x_info.curr_state; + + switch (hdcp_state) { + case H0_HDCP2X_TX_NO_RX_ATTACHED: + status = hdcp2x_tx_idle_state(hdcp2x_tx); + break; + case H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE: + status = hdcp2x_tx_wait_for_tx_state(hdcp2x_tx); + break; + case A0_HDCP2X_TX_AKE_INIT: + status = hdcp2x_tx_write_ake_init(hdcp2x_tx); + break; + case A1_HDCP2X_TX_EXCHANGE_KM: + status = hdcp2x_tx_exchange_km_process(hdcp2x_tx); + break; + case A1_HDCP2X_TX_WAIT_FOR_ACK: + status = hdcp2x_tx_wait_for_ack(hdcp2x_tx); + break; + case A1_HDCP2X_TX_WAIT_FOR_HPRIME: + status = hdcp2x_tx_wait_for_hprime_msg(hdcp2x_tx); + break; + case A1_HDCP2X_TX_WAIT_FOR_PAIRING: + status = hdcp2x_tx_wait_for_pairing_info(hdcp2x_tx); + break; + case A1_HDCP2X_TX_VERIFY_HPRIME: + status = hdcp2x_tx_compute_hprime(hdcp2x_tx); + break; + case A2_HDCP2X_TX_LC_CHECK: + status = hdcp2x_tx_lc_check(hdcp2x_tx); + break; + case A2_HDCP2X_TX_VERIFY_LPRIME: + status = hdcp2x_tx_verify_lprime_msg(hdcp2x_tx); + break; + case A3_HDCP2X_TX_EXCHANGE_KS: + status = hdcp2x_tx_exchange_ks(hdcp2x_tx); + break; + case A4_HDCP2X_TX_REPEATER_CHECK: + status = hdcp2x_tx_rptr_check(hdcp2x_tx); + break; + case A5_HDCP2X_TX_AUTHENTICATED: + status = hdcp2x_tx_authenticated(hdcp2x_tx); + break; + case A6_HDCP2X_TX_WAIT_FOR_RCVID: + status = hdcp2x_tx_wait_for_rcvid(hdcp2x_tx); + break; + case A7_HDCP2X_TX_VERIFY_RCVID: + status = hdcp2x_tx_process_rcvid(hdcp2x_tx); + break; + case A9_HDCP2X_TX_STREAM_MANAGE: + status = hdcp2x_tx_process_stream_manage(hdcp2x_tx); + break; + case A9_HDCP2X_TX_VERIFY_MPRIME: + status = hdcp2x_tx_verify_mprime(hdcp2x_tx); + break; + default: + status = hdcp_state; + dev_dbg(hdcp2x_tx->dev, "Invalid HDCP State"); + break; + } + + return status; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xhdcp2x_tx.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xhdcp2x_tx.h @@ -0,0 +1,296 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx HDCP2X Protocol Driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + */ + +#ifndef _XHDCP2X_TX_H_ +#define _XHDCP2X_TX_H_ + +#include +#include + +#define HDCP2X_TX_SRM_ID 0x91 +#define HDCP2X_TX_REPEATERAUTH_STREAM_READY_SIZE 33 + +#define HDCP2X_TX_V_SIZE 32 +#define HDCP2X_TX_MAX_DEV_COUNT 32 +#define HDCP2X_TX_K_SIZE 2 +#define HDCP2X_TX_STREAMID_TYPE_SIZE 2 +#define HDCP2X_TX_SHA256_HASH_SIZE 32 +#define HDCP2X_TX_AES128_SIZE 16 +#define HDCP2X_TX_KM_SIZE HDCP2X_TX_AES128_SIZE +#define HDCP2X_TX_KM_MSK_SEED_SIZE HDCP2X_TX_SHA256_HASH_SIZE +#define HDCP2X_TX_KS_SIZE 16 + +#define HDCP2X_TX_CERT_PUB_KEY_N_SIZE 128 +#define HDCP2X_TX_CERT_PUB_KEY_E_SIZE 3 +#define HDCP2X_TX_CERT_RSVD_SIZE 2 +#define HDCP2X_TX_CERT_RSA_PARAMETER_SIZE 384 +#define HDCP2X_TX_CERT_SIGNATURE_SIZE 384 +#define HDCP2X_TX_CERT_PADDING_BYTES 330 +#define HDCP2X_TX_CERT_PADDING_END_DELIMITER 332 +#define HDCP2X_TX_CERT_PADDING_TI_IDENTIFIER 333 +#define HDCP2X_TX_CERT_PADDING_T_HASH 352 +#define HDCP2X_TX_SRM_SIGNATURE_SIZE 384 +#define HDCP2X_TX_CERT_TI_IDENTIFIER_SIZE 19 +#define HDCP2X_TX_CERT_T_HASH_SIZE 19 +#define HDCP2X_TX_CERT_SIZE (HDCP_2_2_RECEIVER_ID_LEN + \ + HDCP2X_TX_CERT_PUB_KEY_N_SIZE + \ + HDCP2X_TX_CERT_PUB_KEY_E_SIZE + \ + HDCP2X_TX_CERT_RSVD_SIZE + \ + HDCP2X_TX_CERT_SIGNATURE_SIZE) +#define HDCP2X_TX_CERT_PUBLIC_EXPONENT_E 4 +#define HDCP2X_TX_DKEY 15 +#define HDCP2X_TX_DKEY_CTR1 1 +#define HDCP2X_TX_DKEY_CTR2 2 +#define HDCP2X_TX_DKEY_SIZE 2 + +#define HDCP2X_TX_TXCAPS_SIZE 3 +#define HDCP2X_TX_KPUB_DCP_LLC_N_SIZE 384 +#define HDCP2X_TX_KPUB_DCP_LLC_E_SIZE 1 + +#define HDCP2X_TX_HDCPPORT_E_KPUB_KM_SIZE 128 +#define HDCP2X_TX_HDCPPORT_CERT_RX_SIZE 522 +#define HDCP2X_TX_HDCPPORT_K_SIZE 2 +#define HDCP2X_TX_HDCPPORT_TYPE_VALUE_SIZE 1 + +#define XDPTX_HDCP2X_DPCD_OFFSET 0x69000 +#define HDCP2X_TX_HDCPPORT_M_OFFSET (0x2B0 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_R_TX_OFFSET (0x000 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_TX_CAPS_OFFSET (0x008 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_CERT_RX_OFFSET (0x00B + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_R_RX_OFFSET (0x215 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_RX_CAPS_OFFSET (0x21D + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_E_KPUB_KM_OFFSET (0x220 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_E_KH_KM_OFFSET (0x2A0 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_H_PRIME_OFFSET (0x2C0 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_E_KH_KM_PAIRING_OFFSET (0x2E0 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_R_N_OFFSET (0x2F0 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_L_PRIME_OFFSET (0x2F8 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_E_DKEY_KS_OFFSET (0x318 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_R_IV_OFFSET (0x328 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_RX_INFO_OFFSET (0x330 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_SEQ_NUM_V_OFFSET (0x332 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_V_PRIME_OFFSET (0x335 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_RCVR_ID_LST_OFFSET (0x345 + XDPTX_HDCP2X_DPCD_OFFSET) + +#define HDCP2X_TX_HDCPPORT_RCVR_ID_LST_MAX_SIZE 155 +#define HDCP2X_TX_HDCPPORT_V_OFFSET (GENMASK(9, 5) + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_SEQ_NUM_M_OFFSET (GENMASK(9, 4) + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_K_OFFSET (0x3F3 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_STREAM_ID_TYPE_OFFSET (0x3F5 + XDPTX_HDCP2X_DPCD_OFFSET) + +#define HDCP2X_TX_HDCPPORT_STREAM_ID_TYPE_SIZE 2 +#define HDCP2X_TX_HDCPPORT_M_PRIME_OFFSET (0x473 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_RX_STATUS_OFFSET (0x493 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_TYPE_VALUE_OFFSET (0x494 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_VERSION_OFFSET (0x50 + XDPTX_HDCP2X_DPCD_OFFSET) +#define HDCP2X_TX_HDCPPORT_RX_CAPS_OFFSET (0x21D + XDPTX_HDCP2X_DPCD_OFFSET) + +#define HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET BIT(5) +#define HDCP2X_TX_HDCPPORT_RXSTATUS_OFFSET BIT(6) +#define HDCP2X_TX_HDCPPORT_READ_MSG_OFFSET BIT(7) + +#define HDCP2x_TX_REPEATER_MAX_CASCADE_DEPTH 4 +#define HDCP2X_TX_REVOCATION_LIST_MAX_DEVICES 944 +#define HDCP2X_TX_MAX_ALLOWED_LOCALITY_CHECKS 8 +#define HDCP2X_TX_TYPE_VALUE 18 + +#define HDCP2X_TX_WAIT_REAUTH_CHECK_TIMEOUT 1000 +#define HDCP2X_TX_WAIT_FOR_ENCRYPTION_TIMEOUT 200 +#define HDCP2X_TX_WAIT_FOR_STREAM_TYPE_TIMEOUT 50 + +#define HDCP2X_TX_LEGACY2X_DEVICE_DOWNSTREAM(x) ((x) & BIT(1)) +#define HDCP2X_TX_LEGACY1X_DEVICE_DOWNSTREAM(x) ((x) & BIT(0)) + +/* + * HDCP Authentication Protocol messages in + * HDCP2.3 specification. Section 4.1 + * https://www.digital-cp.com/sites/default/files/ + * HDCP%20Interface%20Independent%20Adaptation%20Specification%20Rev2_3.pdf + */ +struct hdcp2x_tx_ake_init { + u8 msg_id; + u8 r_tx[HDCP_2_2_RTX_LEN]; + u8 txcaps[HDCP2X_TX_TXCAPS_SIZE]; +} __packed; + +struct hdcp2x_tx_ake_no_stored_km { + u8 msg_id; + u8 ek_pubkm[HDCP_2_2_E_KPUB_KM_LEN]; +} __packed; + +struct hdcp2x_tx_ake_stored_km { + u8 msg_id; + u8 ekh_km[HDCP_2_2_E_KH_KM_LEN]; + u8 r_tx[HDCP_2_2_RTX_LEN]; + u8 r_rx[HDCP_2_2_RRX_LEN]; +} __packed; + +struct hdcp2x_tx_lc_init { + u8 msg_id; + u8 rn[HDCP_2_2_RN_LEN]; +} __packed; + +struct hdcp2x_tx_ske_send_eks { + u8 msg_id; + u8 edkeys_ks[HDCP_2_2_E_DKEY_KS_LEN]; + u8 riv[HDCP_2_2_RIV_LEN]; +} __packed; + +struct hdcp2x_tx_rpt_auth_send_ack { + u8 msg_id; + u8 V[HDCP_2_2_V_PRIME_HALF_LEN]; +} __packed; + +struct hdcp2x_tx_rpt_auth_stream_manage { + u8 msg_id; + u8 seq_num_m[HDCP_2_2_SEQ_NUM_LEN]; + u8 K[HDCP2X_TX_K_SIZE]; + u8 streamid_type[HDCP2X_TX_STREAMID_TYPE_SIZE]; +} __packed; + +struct hdcp2x_tx_cert_rx { + u8 rcvid[HDCP_2_2_RECEIVER_ID_LEN]; + u8 N[HDCP2X_TX_CERT_PUB_KEY_N_SIZE]; + u8 e[HDCP2X_TX_CERT_PUB_KEY_E_SIZE]; + u8 reserved[HDCP2X_TX_CERT_RSVD_SIZE]; + u8 signature[HDCP2X_TX_CERT_SIGNATURE_SIZE]; +} __packed; + +struct hdcp2x_tx_ake_sendcert { + u8 msg_id; + struct hdcp2x_tx_cert_rx cert_rx; + u8 r_rx[HDCP_2_2_RRX_LEN]; + u8 rxcaps[HDCP_2_2_RXCAPS_LEN]; +} __packed; + +struct hdcp2x_tx_ake_send_pairing_info { + u8 msg_id; + u8 ekh_km[HDCP_2_2_E_KH_KM_LEN]; +} __packed; + +struct hdcp2x_tx_lc_send_lc_prime { + u8 msg_id; + u8 lprime[HDCP_2_2_L_PRIME_LEN]; +} __packed; + +struct hdcp2x_tx_rpt_auth_send_rcvid_list { + u8 msg_id; + u8 rxinfo[HDCP_2_2_RXINFO_LEN]; + u8 seq_num_v[HDCP_2_2_SEQ_NUM_LEN]; + u8 vprime[HDCP_2_2_V_PRIME_HALF_LEN]; + u8 rcvids[HDCP_2_2_MAX_DEVICE_COUNT][HDCP_2_2_RECEIVER_ID_LEN]; +} __packed; + +struct hdcp2x_tx_rpt_auth_stream_ready { + u8 msg_id; + u8 m_prime[HDCP_2_2_MPRIME_LEN]; +} __packed; + +struct hdcp2x_tx_ake_sendprime { + u8 msg_id; + u8 h_prime[HDCP_2_2_H_PRIME_LEN]; +} __packed; + +struct hdcp2x_tx_certrx { + u8 rcvid[HDCP_2_2_RECEIVER_ID_LEN]; + u8 N[HDCP2X_TX_CERT_PUB_KEY_N_SIZE]; + u8 e[HDCP2X_TX_CERT_PUB_KEY_E_SIZE]; + u8 rsvd[HDCP2X_TX_CERT_RSVD_SIZE]; + u8 signature[HDCP2X_TX_CERT_SIGNATURE_SIZE]; +} __packed; + +struct hdcp2x_tx_pairing_info { + u8 rcvid[HDCP_2_2_RECEIVER_ID_LEN]; + u8 rxcaps[HDCP_2_2_RXCAPS_LEN]; + u8 rtx[HDCP_2_2_RTX_LEN]; + u8 rrx[HDCP_2_2_RRX_LEN]; + u8 km[HDCP_2_2_E_KH_KM_LEN]; + u8 ekh_km[HDCP_2_2_E_KH_KM_LEN]; + u8 ready; +} __packed; + +struct hdcp2x_tx_revoclist { + u8 rcvid[HDCP2X_TX_REVOCATION_LIST_MAX_DEVICES][HDCP_2_2_RECEIVER_ID_LEN]; + u32 num_of_devices; +} __packed; + +struct hdcp2x_tx_topology { + u8 rcvid[HDCP2X_TX_MAX_DEV_COUNT][HDCP_2_2_RECEIVER_ID_LEN]; + u8 depth; + u8 devicecount; + u8 max_dev_exceeded; + u8 max_cascaded_exceeded; + u8 hdcp2x_legacy_ds; + u8 hdcp1x_legacy_ds; +} __packed; + +/** + * union hdcp2x_tx_msg_type - HDCP 2X authentication protocol message buffers + * @ake_send_cert: Reads CertRx message + * @ake_send_prime: Reads HPrime message + * @ake_send_pairing_info: Reads Ekh_km message + * @lcsend_lcprime: Reads L` prime message + * @rpt_auth_send_rcvid: Reads receiver-id list message + * @rpt_auth_stream_rdy: Reads M` message + * @ake_int: Writes Txcaps and RTx message + * @ake_nostored_km: Writes Ekubkm message + * @ake_stored_km: Writes Ekh_km message + * @lcinit: Writes Rn message + * @ske_send_eks: Writes Edkey(ks) and riv message + * @rpt_auth_send_ack: Writes acknowledgment to the rcv-id list message + * @rpt_auth_stream_mng: Writes content type value to the HDCP receiver + * @msg_id: Identification id for messages + */ +union hdcp2x_tx_msg_type { + u8 msg_id; + struct hdcp2x_tx_ake_sendcert ake_send_cert; + struct hdcp2x_tx_ake_sendprime ake_send_prime; + struct hdcp2x_tx_ake_send_pairing_info ake_send_pairing_info; + struct hdcp2x_tx_lc_send_lc_prime lcsend_lcprime; + struct hdcp2x_tx_rpt_auth_send_rcvid_list rpt_auth_send_rcvid; + struct hdcp2x_tx_rpt_auth_stream_ready rpt_auth_stream_rdy; + struct hdcp2x_tx_ake_init ake_int; + struct hdcp2x_tx_ake_no_stored_km ake_nostored_km; + struct hdcp2x_tx_ake_stored_km ake_stored_km; + struct hdcp2x_tx_lc_init lcinit; + struct hdcp2x_tx_ske_send_eks ske_send_eks; + struct hdcp2x_tx_rpt_auth_send_ack rpt_auth_send_ack; + struct hdcp2x_tx_rpt_auth_stream_manage rpt_auth_stream_mng; +}; + +/* + * HDCP Transmitter State Diagram available in + * HDCP2.3 specification. Section 2.8 + * https://www.digital-cp.com/sites/default/files/ + * HDCP%20Interface%20Independent%20Adaptation%20Specification%20Rev2_3.pdf + */ +/* HDCP 2X authentication protocol states */ +enum hdcp2x_tx_state { + H0_HDCP2X_TX_NO_RX_ATTACHED = 0x00, + H1_HDCP2X_TX_WAIT_FOR_TX_ENABLE = 0x01, + A0_HDCP2X_TX_AKE_INIT = 0x02, + A1_HDCP2X_TX_EXCHANGE_KM = 0x03, + A1_HDCP2X_TX_WAIT_FOR_ACK = 0x04, + A1_HDCP2X_TX_WAIT_FOR_HPRIME = 0x05, + A1_HDCP2X_TX_WAIT_FOR_PAIRING = 0x06, + A1_HDCP2X_TX_VERIFY_HPRIME = 0x07, + A2_HDCP2X_TX_LC_CHECK = 0x08, + A2_HDCP2X_TX_VERIFY_LPRIME = 0x09, + A3_HDCP2X_TX_EXCHANGE_KS = 0x0A, + A4_HDCP2X_TX_REPEATER_CHECK = 0x0B, + A5_HDCP2X_TX_AUTHENTICATED = 0x0C, + A6_HDCP2X_TX_WAIT_FOR_RCVID = 0x0D, + A7_HDCP2X_TX_VERIFY_RCVID = 0x0E, + A8_HDCP2X_TX_SEND_RCVID_ACK = 0x0F, + A9_HDCP2X_TX_STREAM_MANAGE = 0x10, + A9_HDCP2X_TX_VERIFY_MPRIME = 0x11, + HDCP2X_TX_NUM_STATES = 0x12 +}; + +#endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp1x_keymngt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp1x_keymngt.c @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx Specific HDCP1x driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Katta Dhanunjanrao + * + */ + +#include +#include + +#include "xlnx_hdcp_tx.h" +#include "xhdcp1x_tx.h" +#include "xlnx_hdcp1x_tx.h" +#include "xlnx_hdcp2x_tx.h" + +/* DEBUG CONSTANTS */ +#define HDCP1X_KEYMGMT_REG_VERSION 0x0000 +#define HDCP1X_KEYMGMT_REG_TYPE 0x0004 +#define HDCP1X_KEYMGMT_REG_CTRL 0x000C +#define HDCP1X_KEYMGMT_REG_TBL_CTRL 0x0020 +#define HDCP1X_KEYMGMT_REG_TBL_STATUS 0x0024 +#define HDCP1X_KEYMGMT_REG_TBL_ADDR 0x0028 +#define HDCP1X_KEYMGMT_REG_TBL_DAT_H 0x002C +#define HDCP1X_KEYMGMT_REG_TBL_DAT_L 0x0030 + +#define HDCP1X_KEYMGMT_REG_CTRL_RST_MASK BIT(31) +#define HDCP1X_KEYMGMT_REG_CTRL_DISABLE_MASK GENMASK(31, 1) +#define HDCP1X_KEYMGMT_REG_CTRL_ENABLE_MASK BIT(0) +#define HDCP1X_KEYMGMT_REG_TBL_STATUS_RETRY 0x400 +#define HDCP1X_KEYMGMT_TBLID_0 0 +#define HDCP1X_KEYMGMT_REG_TBL_CTRL_WR_MASK BIT(0) +#define HDCP1X_KEYMGMT_REG_TBL_CTRL_RD_MASK BIT(1) +#define HDCP1X_KEYMGMT_REG_TBL_CTRL_EN_MASK BIT(31) +#define HDCP1X_KEYMGMT_REG_TBL_STATUS_DONE_MASK BIT(0) +#define HDCP1X_KEYMGMT_MAX_TBLS 8 +#define HDCP1X_KEYS_SIZE 336 +#define HDCP1X_KEYMGMT_MAX_ROWS_PER_TBL 41 + +union hdcp1x_key_table { + u8 data_u8[HDCP1X_KEYS_SIZE]; + u64 data_u64[HDCP1X_KEYS_SIZE / (sizeof(u64))]; +}; + +/* Register related operations */ +static inline void xdptx_hdcp1x_keymgmt_reset(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 data; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_CTRL, &data)) + return; + data |= HDCP1X_KEYMGMT_REG_CTRL_RST_MASK; + if (regmap_update_bits(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_CTRL, HDCP1X_KEYMGMT_REG_CTRL_RST_MASK, + data)) + return; + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_CTRL, &data)) + return; + data &= ~HDCP1X_KEYMGMT_REG_CTRL_RST_MASK; + regmap_update_bits(xhdcp1x_tx->hdcp1x_keymgmt_base, HDCP1X_KEYMGMT_REG_CTRL, + HDCP1X_KEYMGMT_REG_CTRL_RST_MASK, data); +} + +static inline void xdptx_hdcp1x_keymgmt_enable(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 data; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_CTRL, &data)) + return; + data |= HDCP1X_KEYMGMT_REG_CTRL_ENABLE_MASK; + if (regmap_update_bits(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_CTRL, HDCP1X_KEYMGMT_REG_CTRL_ENABLE_MASK, + data)) + return; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_CTRL, &data)) + return; + data |= HDCP1X_KEYMGMT_REG_TBL_CTRL_EN_MASK; + regmap_update_bits(xhdcp1x_tx->hdcp1x_keymgmt_base, HDCP1X_KEYMGMT_REG_TBL_CTRL, + HDCP1X_KEYMGMT_REG_TBL_CTRL_EN_MASK, data); +} + +static inline void xdptx_hdcp1x_keymgmt_disable(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 data; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_CTRL, &data)) + return; + data &= HDCP1X_KEYMGMT_REG_CTRL_DISABLE_MASK; + regmap_update_bits(xhdcp1x_tx->hdcp1x_keymgmt_base, HDCP1X_KEYMGMT_REG_CTRL, + HDCP1X_KEYMGMT_REG_CTRL_DISABLE_MASK, data); +} + +static int xdptx_hdcp1x_keymgmt_is_table_config_done(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + int retry = HDCP1X_KEYMGMT_REG_TBL_STATUS_RETRY; + u32 data; + + while (retry) { + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_STATUS, &data)) + return 0; + if (!(data & HDCP1X_KEYMGMT_REG_TBL_STATUS_DONE_MASK)) + break; + retry--; + usleep_range(50, 100); + } + + return retry; +} + +static int xdptx_hdcp1x_keymgmt_table_read(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u8 table_id, u8 row_id, u64 *read_val) +{ + u64 temp; + u32 addr, data; + + addr = table_id; + addr <<= BITS_PER_BYTE; + addr |= row_id; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_CTRL, &data)) + return -EIO; + data &= ~HDCP1X_KEYMGMT_REG_TBL_CTRL_WR_MASK; + data |= HDCP1X_KEYMGMT_REG_TBL_CTRL_RD_MASK; + if (regmap_write(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_CTRL, data)) + return -EIO; + if (regmap_write(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_ADDR, addr)) + return -EIO; + if (!xdptx_hdcp1x_keymgmt_is_table_config_done(xhdcp1x_tx)) + return -EIO; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_DAT_H, &data)) + return -EIO; + temp = data; + temp <<= BITS_PER_BYTE * sizeof(u32); + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_DAT_L, &data)) + return -EIO; + temp |= data; + *read_val = temp; + + return 0; +} + +static int xdptx_hdcp1x_keymgmt_table_write(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u8 table_id, u8 row_id, u64 write_val) +{ + u32 addr, data; + + if (regmap_write(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_DAT_L, + lower_32_bits(write_val))) + return -EIO; + if (regmap_write(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_DAT_H, + upper_32_bits(write_val))) + return -EIO; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_CTRL, &data)) + return -EIO; + data &= ~HDCP1X_KEYMGMT_REG_TBL_CTRL_RD_MASK; + data |= HDCP1X_KEYMGMT_REG_TBL_CTRL_WR_MASK; + if (regmap_write(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_CTRL, data)) + return -EIO; + + addr = table_id; + addr <<= BITS_PER_BYTE; + addr |= row_id; + if (regmap_write(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TBL_ADDR, addr)) + return -EIO; + if (!xdptx_hdcp1x_keymgmt_is_table_config_done(xhdcp1x_tx)) + return -EIO; + + return 0; +} + +static void xdptx_hdcp1x_keymgmt_get_num_of_tables_rows(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u8 *num_tables, u8 *num_rows_per_table) +{ + u32 data; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TYPE, &data)) + return; + + if (data) { + *num_tables = (data >> 8) & 0xFF; + *num_rows_per_table = data & 0xFF; + } else { + *num_tables = HDCP1X_KEYMGMT_MAX_TBLS; + *num_rows_per_table = HDCP1X_KEYMGMT_MAX_ROWS_PER_TBL; + } +} + +static int xdptx_hdcp1x_keymgmt_init_tables(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + int ret = 0; + u8 num_tables = 0, num_rows_per_table = 0, table_id, row_id; + + xdptx_hdcp1x_keymgmt_get_num_of_tables_rows(xhdcp1x_tx, &num_tables, + &num_rows_per_table); + for (table_id = 0; table_id < num_tables; table_id++) + for (row_id = 0; row_id < num_rows_per_table; row_id++) + if (xdptx_hdcp1x_keymgmt_table_write(xhdcp1x_tx, table_id, + row_id, 0)) + return -EIO; + return ret; +} + +static int xdptx_hdcp1x_keymgmt_load_keys(struct xlnx_hdcp1x_config *xhdcp1x_tx, + union hdcp1x_key_table *key_table, + u32 key_table_size) +{ + int ret = 0; + u8 row_id; + + for (row_id = 0; row_id < (key_table_size / sizeof(u64)); row_id++) + if (xdptx_hdcp1x_keymgmt_table_write(xhdcp1x_tx, HDCP1X_KEYMGMT_TBLID_0, + row_id, key_table->data_u64[row_id])) + ret = -EIO; + + return ret; +} + +static int xdptx_hdcp1x_keymgmt_verify_keys(struct xlnx_hdcp1x_config *xhdcp1x_tx, + union hdcp1x_key_table *key_table, + u32 key_table_size) +{ + u64 data; + int ret = 0; + u8 row_id; + + for (row_id = 0; row_id < (key_table_size / sizeof(u64)); row_id++) { + data = 0; + xdptx_hdcp1x_keymgmt_table_read(xhdcp1x_tx, HDCP1X_KEYMGMT_TBLID_0, + row_id, &data); + if (data != key_table->data_u64[row_id]) + ret = -EIO; + } + + return ret; +} + +static int xdptx_hdcp1x_keymgmt_set_key(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + union hdcp1x_key_table key_table; + int ret = 0; + u32 version, type; + u8 index; + + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_VERSION, &version)) + return -EIO; + if (regmap_read(xhdcp1x_tx->hdcp1x_keymgmt_base, + HDCP1X_KEYMGMT_REG_TYPE, &type)) + return -EIO; + if (!version && !type) { + dev_err(xhdcp1x_tx->dev, "hdcp1x keymgmt core is not present\n"); + return -ENODEV; + } + + xdptx_hdcp1x_keymgmt_reset(xhdcp1x_tx); + ret = xdptx_hdcp1x_keymgmt_init_tables(xhdcp1x_tx); + if (ret) + return ret; + xdptx_hdcp1x_keymgmt_disable(xhdcp1x_tx); + memcpy(key_table.data_u8, xhdcp1x_tx->hdcp1x_key, HDCP1X_KEYS_SIZE); + /* adjust the endian-ness to host order */ + for (index = 0; index < HDCP1X_KEYS_SIZE / sizeof(u64); index++) + key_table.data_u64[index] = + be64_to_cpu(*((__be64 *)&key_table.data_u64[index])); + + ret = xdptx_hdcp1x_keymgmt_load_keys(xhdcp1x_tx, &key_table, + HDCP1X_KEYS_SIZE); + if (ret) + return ret; + ret = xdptx_hdcp1x_keymgmt_verify_keys(xhdcp1x_tx, &key_table, + HDCP1X_KEYS_SIZE); + if (ret) + return ret; + xdptx_hdcp1x_keymgmt_enable(xhdcp1x_tx); + + return ret; +} + +static int xdptx_hdcp1x_key_write(struct xlnx_hdcp1x_config *xhdcp1x_tx, u8 *data) +{ + int ret = 0; + + xhdcp1x_tx->hdcp1x_key = devm_kzalloc(xhdcp1x_tx->dev, HDCP1X_KEYS_SIZE, + GFP_KERNEL); + if (!xhdcp1x_tx->hdcp1x_key) + return -ENOMEM; + + memcpy(xhdcp1x_tx->hdcp1x_key, data, HDCP1X_KEYS_SIZE); + xhdcp1x_tx->hdcp1x_key_available = true; + ret = xdptx_hdcp1x_keymgmt_set_key(xhdcp1x_tx); + + if (ret < 0) + return ret; + + xhdcp1x_tx_set_keyselect(xhdcp1x_tx, 0); + xhdcp1x_tx_load_aksv(xhdcp1x_tx); + //msleep(5); + + return ret; +} + +int xlnx_hdcp1x_keymngt_init(struct xlnx_hdcp1x_config *xhdcp1x_tx, u8 *data) +{ + int ret = 0; + + if (!(xhdcp1x_tx->keyinit)) { + /* Key Management Initialize */ + ret = xdptx_hdcp1x_key_write(xhdcp1x_tx, data); + if (ret < 0) + return ret; + xhdcp1x_tx->keyinit = true; + } + + return ret; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp1x_tx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp1x_tx.c @@ -0,0 +1,1282 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx HDCP1X Protocol Driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Katta Dhanunjanrao + * + * This driver provides standard HDCP1X protocol specific functionalites. + * It consists of: + * - A state machine which handles the states as specified in the HDCP + * specification. + * This driver still have Xilinx specific functionalities as it is not upstreamed now, + * it will be updated as more generic and standardized driver in the next upstream version. + * + * Reference : + * https://www.digital-cp.com/sites/default/files/specifications/HDCP%20on%20DisplayPort%20Specification%20Rev1_1.pdf + * + */ + +#include +#include +#include +#include "xlnx_hdcp_tx.h" +#include "xlnx_hdcp_sha1.h" +#include "xlnx_hdcp1x_tx.h" +#include "xhdcp1x_tx.h" + +#define XHDCP1X_WRITE_CHUNK_SZ 8 +#define XHDCP1X_WRITE_ADDRESS_OFFSET 0x100 + +/** + * xlnx_hdcp1x_tx_enble: This function enables the cipher block for An,Aksv generation. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true means sucessfull set or othervalue + */ +static bool xlnx_hdcp1x_tx_enble(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + xhdcp1x_tx->is_enabled = XHDCP1X_ENABLE; + xhdcp1x_tx->is_cipher = xhdcp1x_cipher_enable(xhdcp1x_tx->cipher); + + if (xhdcp1x_tx->is_cipher) + return -EINVAL; + + xlnx_hdcp_tmrcntr_stop(&xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr, + XTC_TIMER_0); + + return true; +} + +/** + * xlnx_hdcp1x_tx_start_authenticate: This function sets the initial states for HDCP state machine + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true means sucessfull set or othervalue + */ +static bool xlnx_hdcp1x_tx_start_authenticate(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + if (!(xhdcp1x_tx->is_enabled)) + return -EINVAL; + + xhdcp1x_tx->auth_status = XHDCP1X_TX_AUTHENTICATION_BUSY; + xhdcp1x_tx->curr_state = H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; + xhdcp1x_tx->prev_state = H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; + return true; +} + +/** + * xlnx_hdcp1x_tx_process_ri_event: This function provides an indication + * whether RI updation is done in hardware or not + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: none + */ +void xlnx_hdcp1x_tx_process_ri_event(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + xhdcp1x_tx->is_riupdate = true; +} + +/** + * xlnx_start_hdcp1x_engine: This function calls necessary functions for HDCP state machine. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: nothing + */ +void xlnx_start_hdcp1x_engine(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + xlnx_hdcp1x_tx_enble(xhdcp1x_tx); + xlnx_hdcp1x_tx_start_authenticate(xhdcp1x_tx); +} + +/** + * xlnx_hdcp1x_tx_init: This function initilizes cipher and set defaults. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * @is_repeater: the downstream is repeater or monitor. + * + * @return: true means init sucessfull or flase/other value + */ +bool xlnx_hdcp1x_tx_init(struct xlnx_hdcp1x_config *xhdcp1x_tx, bool is_repeater) +{ + /* Default Configuration */ + xhdcp1x_tx->pending_events = XHDCP1X_DEFAULT_INIT; + xhdcp1x_tx->curr_state = XHDCP1X_DEFAULT_INIT; + xhdcp1x_tx->prev_state = XHDCP1X_DEFAULT_INIT; + xhdcp1x_tx->is_encryption_en = XHDCP1X_DEFAULT_INIT; + xhdcp1x_tx->encryption_map = XHDCP1X_DEFAULT_INIT; + xhdcp1x_tx->is_enabled = XHDCP1X_ENABLE; + if (is_repeater) { + dev_info(xhdcp1x_tx->dev, "Hdcp1x Repeater Functionality is not supported\n"); + return false; + } + /* initialize the Cipher core */ + xhdcp1x_tx->cipher = xhdcp1x_cipher_init(xhdcp1x_tx->dev, + xhdcp1x_tx->interface_base); + if (IS_ERR(xhdcp1x_tx->cipher)) + return -EINVAL; + + return true; +} + +/** + * xlnx_hdcp1x_task_monitor: This function monitors the HDCP states. + * @xhdcp1x_tx: reference to the HDCP config structure + * + * @return: it return the HDCP state + */ +int xlnx_hdcp1x_task_monitor(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + enum hdcp1x_tx_state new_state; + + new_state = hdcp1x_tx_protocol_authenticate_sm(xhdcp1x_tx); + xhdcp1x_tx->prev_state = xhdcp1x_tx->curr_state; + xhdcp1x_tx->curr_state = new_state; + + return xhdcp1x_tx->stats.auth_status; +} + +static int xlnx_hdcp1x_tx_writedata(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u8 offset, + const void *buf, u32 buf_size) +{ + u8 slave = DRM_HDCP_DDC_ADDR; + u8 tx_buf[XHDCP1X_WRITE_CHUNK_SZ + 1]; + int num_written = 0; + u32 this_time = 0; + const u8 *write_buf = buf; + + if ((buf_size + offset) > XHDCP1X_WRITE_ADDRESS_OFFSET) + buf_size = (XHDCP1X_WRITE_ADDRESS_OFFSET - offset); + do { + this_time = XHDCP1X_WRITE_CHUNK_SZ; + if (this_time > buf_size) + this_time = buf_size; + tx_buf[0] = offset; + memcpy(&tx_buf[1], write_buf, this_time); + if (xhdcp1x_tx->handlers.wr_handler(xhdcp1x_tx->interface_ref, + slave, + tx_buf, + (this_time + 1)) < 0) { + num_written = -1; + break; + } + num_written += this_time; + write_buf += this_time; + buf_size -= this_time; + } while ((buf_size != 0) && (num_written > 0)); + + return num_written; +} + +/** + * xlnx_hdcp1x_downstream_capbility: This function queries the downstream device to check + * if the downstream device is HDCP capable. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true indicates HDCP capable or not (false) + */ +bool xlnx_hdcp1x_downstream_capbility(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 value[XHDMI_HDCP1X_PORT_SIZE_BSTATUS] = {0}; + u8 rxcaps = 0; + + if (xhdcp1x_tx->protocol == XHDCP1X_TX_HDMI) { + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BCAPS, + value, 2); + if (value[0] & 0x80) { + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BSTATUS, + value, XHDMI_HDCP1X_PORT_SIZE_BSTATUS); + return 1; + } + + return 0; + } + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BCAPS, + (void *)&rxcaps, + XHDCP1X_REMOTE_INFO_BCAPS_VAL); + + return (rxcaps & XHDCP1X_PORT_BIT_BCAPS_HDCP_CAPABLE); +} + +/** + * xlnx_hdcp1x_tx_check_rxcapable: This function ensure that remote end is HDCP capable. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true indicates HDCP capable remote end or not (false) + */ +bool xlnx_hdcp1x_tx_check_rxcapable(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 value = 0; + + xlnx_hdcp1x_tx_disable_encryption(xhdcp1x_tx, XHDCP1X_STREAM_MAP); + xhdcp1x_tx->is_encryption_en = XHDCP1X_DEFAULT_INIT; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + if ((xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BCAPS, + &value, + XHDMI_HDCP1X_PORT_SIZE_BCAPS)) > 0) { + if ((value & 0x80)) { + xlnx_hdcp_tmrcntr_stop(&xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr, + XTC_TIMER_0); + return true; + } + } + } + /* Check the Rx HDCP Capable or Not */ + if (xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BCAPS, + &value, XHDCP1X_REMOTE_INFO_BCAPS_VAL)) { + if (value & XHDCP1X_PORT_BIT_BCAPS_HDCP_CAPABLE) + return true; + } + dev_dbg(xhdcp1x_tx->dev, "HDCP1x RX Not Capable"); + + return false; +} + +/** + * xlnx_hdcp1x_read_bksv_from_remote: This function reads the bksv from the remote. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * @offset: the remote HDCP bksv offset + * @buf: the remote bksv value stored in buffer + * @buf_size: the size of the bskv + * + * @return: true indicates read sucessfull or not (false) + */ +bool xlnx_hdcp1x_read_bksv_from_remote(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u32 offset, void *buf, u32 buf_size) +{ + if ((buf_size + (offset - XDPTX_HDCP1X_DPCD_OFFSET)) > XHDCP1X_BUF_OFFSET_LEN) + buf_size = (XHDCP1X_BUF_OFFSET_LEN - offset); + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + offset, + buf, buf_size); + + return true; +} + +static void xlnx_hdcp1x_uint_to_buf(u8 *buf, u64 resval, u32 size) +{ + int byte; + + if ((size) > 0) { + for (byte = 0; byte <= (int)(((size) - 1) >> 3); byte++) { + buf[byte] = (uint8_t)(resval & 0xFFu); + resval >>= XHDCP1X_BYTE_IN_BITS; + } + } +} + +static u64 xlnx_hdcp1x_buf_to_unit(u8 *buf, u32 size) +{ + u64 remoteksv = 0; + int byte; + + if ((size) > 0) { + for (byte = (((size) - 1) >> 3); byte >= 0; byte--) { + remoteksv <<= XHDCP1X_BYTE_IN_BITS; + remoteksv |= buf[byte]; + } + } + return remoteksv; +} + +/** + * xlnx_hdcp1x_tx_test_for_repeater: This function checks the remote end to see if its a repeater. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true indicates sucessfull or not (false) + */ +int xlnx_hdcp1x_tx_test_for_repeater(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 value = 0, ret = 0; + + /* Check For Repeater */ + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + ret = xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BCAPS, + &value, + XHDMI_HDCP1X_PORT_SIZE_BCAPS); + if (ret != XHDMI_HDCP1X_PORT_SIZE_BCAPS) + return false; + if (value & XHDMI_HDCP1X_PORT_BIT_BCAPS_REPEATER) { + xhdcp1x_tx->is_repeater = 1; + return true; + } + + } else { + ret = xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BCAPS, + &value, + XHDMI_HDCP1X_PORT_SIZE_BCAPS); + if (ret != XHDCP1X_PORT_SIZE_BCAPS) + return false; + if (value & XHDCP1X_PORT_BIT_BCAPS_REPEATER) { + xhdcp1x_tx->is_repeater = 1; + return true; + } + } + + return false; +} + +/** + * xlnx_hdcp1x_set_keys: This function loads the key to key management block + * @xhdcp1x_tx: It points to the HDCP1x config structre + * @data: Key information received from sysfs + * + * @return: return 1 indicates success or 0 for failure + */ + +int xlnx_hdcp1x_set_keys(struct xlnx_hdcp1x_config *xhdcp1x_tx, u8 *data) +{ + int ret = 0; + + ret = xlnx_hdcp1x_keymngt_init(xhdcp1x_tx, data); + return ret; +} + +/** + * xlnx_hdcp1x_exchangeksvs: This function exchanges the ksvs between the two ends of the link. + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true indicates keys exchange sucessfull or not (false) + */ +bool xlnx_hdcp1x_exchangeksvs(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + /* Reading the Downstream Capabilities */ + u8 buf[XHDCP1X_BYTE_IN_BITS] = {XHDCP1X_DEFAULT_INIT}; + u64 remoteksv = XHDCP1X_DEFAULT_INIT; + u64 localksv = XHDCP1X_DEFAULT_INIT, an = XHDCP1X_DEFAULT_INIT; + u8 buf_ainfo[XHDCP1X_PORT_SIZE_AINFO]; + + xlnx_hdcp1x_read_bksv_from_remote(xhdcp1x_tx, XHDCP1X_PORT_OFFSET_BKSV, + buf, XHDCP1X_REMOTE_BKSV_SIZE); + remoteksv = xlnx_hdcp1x_buf_to_unit(buf, + XHDCP1X_PORT_SIZE_BKSV * XHDCP1X_BYTE_IN_BITS); + + /* Check the is KSV valid & revocation list from application data*/ + if (!(xlnx_hdcp1x_is_ksvvalid(remoteksv))) { + dev_dbg(xhdcp1x_tx->dev, "Invalid bksv"); + return false; + } + xhdcp1x_tx->tmr_cnt = 0; + /* Check for repeater */ + if (xlnx_hdcp1x_tx_test_for_repeater(xhdcp1x_tx)) + xhdcp1x_tx->is_repeater = 1; + else + xhdcp1x_tx->is_repeater = 0; + + /* Generate the an */ + an = xlnx_hdcp1x_tx_generate_an(xhdcp1x_tx); + + /* Save the an in statehelp for later use */ + xhdcp1x_tx->state_helper = an; + /* Determine the Local KSV */ + localksv = xhdcp1x_cipher_get_localksv(xhdcp1x_tx->cipher); + /* Load the cipher with the remote ksv */ + xhdcp1x_cipher_set_remoteksv(xhdcp1x_tx->cipher, + remoteksv); + /* Clear AINFO */ + memset(buf_ainfo, XHDCP1X_DEFAULT_INIT, XHDCP1X_PORT_SIZE_AINFO); + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + xlnx_hdcp1x_tx_writedata(xhdcp1x_tx, + XHDMI_HDCP1X_PORT_OFFSET_AINFO, + buf_ainfo, XHDCP1X_PORT_SIZE_AINFO); + else + xhdcp1x_tx->handlers.wr_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_AINFO, + buf_ainfo, XHDCP1X_PORT_SIZE_AINFO); + + xlnx_hdcp1x_uint_to_buf(buf, an, XHDCP1X_PORT_SIZE_AN * XHDCP1X_BYTE_IN_BITS); + /* Send an to Remote */ + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + xlnx_hdcp1x_tx_writedata(xhdcp1x_tx, + XHDMI_HDCP1X_PORT_OFFSET_AN, + buf, XHDCP1X_PORT_SIZE_AN); + else + xhdcp1x_tx->handlers.wr_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_AN, + buf, XHDCP1X_PORT_SIZE_AN); + /* Send Aksv to remote */ + xlnx_hdcp1x_uint_to_buf(buf, localksv, + XHDCP1X_PORT_SIZE_AKSV * XHDCP1X_BYTE_IN_BITS); + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + xlnx_hdcp1x_tx_writedata(xhdcp1x_tx, + XHDMI_HDCP1X_PORT_OFFSET_AKSV, + buf, XHDCP1X_PORT_SIZE_AKSV); + else + xhdcp1x_tx->handlers.wr_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_AKSV, + buf, XHDCP1X_PORT_SIZE_AKSV); + return true; +} + +/** + * xlnx_hdcp1x_computationsstate: This function initiates the computations for a state machine + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true indicates comutations done (true) or not (false) + */ +bool xlnx_hdcp1x_computationsstate(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 X = 0, Y = 0, Z = 0, cipher_req = XHDCP1X_DEFAULT_INIT; + u64 value = XHDCP1X_DEFAULT_INIT; + + /* Update value with an */ + value = xhdcp1x_tx->state_helper; + /* Load the cipher B registers with an */ + X = (u32)(value & 0x0FFFFFFFul); + value >>= 28; + Y = (u32)(value & 0x0FFFFFFFul); + value >>= 28; + Z = (u32)(value & 0x000000FFul); + if (xhdcp1x_tx->is_repeater) + Z |= (1ul << XHDCP1X_BYTE_IN_BITS); + + xhdcp1x_cipher_setb(xhdcp1x_tx->cipher, X, Y, Z); + /* Initiate the block cipher */ + xhdcp1x_cipher_do_request(xhdcp1x_tx->cipher, + XHDCP1X_CIPHER_REQUEST_BLOCK); + cipher_req = xhdcp1x_cipher_is_request_complete(xhdcp1x_tx->cipher); + + if (cipher_req != 1) { + dev_dbg(xhdcp1x_tx->dev, "CipherDoRequest Computations not done"); + return false; + } + + return true; +} + +static u16 xlnx_hdcp1x_buf_to_uint16(u8 *buf, u32 size) +{ + int byte = 0; + u16 buff_to_uint = XHDCP1X_DEFAULT_INIT; + + if ((size) > 0) { + for (byte = (((size) - 1) >> 3); byte >= 0; byte--) { + buff_to_uint <<= XHDCP1X_BYTE_IN_BITS; + buff_to_uint |= buf[byte]; + } + } + return buff_to_uint; +} + +/** + * xlnx_hdcp1x_tx_validaterxstate: This function validates the attached receiver + * @xhdcp1x_tx: It points to the HDCP1x config structure + * + * @return: true indicates key matched (true) or not (false) + */ +bool xlnx_hdcp1x_tx_validaterxstate(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 buf[XHDCP1X_REMOTE_RO_SIZE]; + int ret = 0; + u32 num_tries = XHDCP1X_MAX_RETRIES; + /* 100ms delay: The HDCP transmitter must allow the HDCP receiver at least + * 100ms to make ro' available from the time Aksv is written. added based on + * DP HDCP sepecification: HDCP%20on%20DisplayPort%20Specification%20Rev1_1.pdf + */ + msleep(XHDCP1X_RO_AVILABLE_DELAY); + do { + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + ret = xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_RO, + buf, + XHDMI_HDCP1X_PORT_SIZE_RO); + } else { + ret = xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_RO, + buf, 2); + } + if (ret > 0) { + u16 remotero = 0; + u16 localro = 0; + + /* Determine Remote Ro */ + remotero = xlnx_hdcp1x_buf_to_uint16(buf, + (XHDCP1X_REMOTE_RO_SIZE * + XHDCP1X_BYTE_IN_BITS)); + /* Determine the Local Ro */ + xhdcp1x_cipher_get_ro(xhdcp1x_tx->cipher, &localro); + /* Compare the Ro == Ro' */ + if (localro == remotero) + return true; + } + num_tries--; + } while (num_tries > 0); + + return false; +} + +/** + * xlnx_hdcp1x_is_ksvvalid: This function validates a KSV value as + * having 20 1's and 20 0's + * @ksv: ksv is the value to validate + * + * @return: true value indicates valid (true) or not (false) + */ +int xlnx_hdcp1x_is_ksvvalid(u64 ksv) +{ + u32 is_valid = false, num_ones = 0; + + /* Determine num_ones */ + while (ksv) { + if ((ksv & 1) != 0) + num_ones++; + + ksv >>= 1; + } + + /* Check for 20 1's */ + if (num_ones == XHDCP1X_KSV_NUM_OF_1S) + is_valid = true; + + return is_valid; +} + +/** + * xlnx_hdcp1x_tx_generate_an: This function generates the an from a random number generator + * @xhdcp1x_tx: Instanceptr is the HDCP1x config structure + * + * @return: A 64-bit pseudo random number (an). + */ +u64 xlnx_hdcp1x_tx_generate_an(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u64 an = 0; + /* Attempt to generate an */ + + if (xhdcp1x_cipher_do_request(xhdcp1x_tx->cipher, 2) == 0) { + /* Wait until done */ + while (!xhdcp1x_cipher_is_request_complete(xhdcp1x_tx->cipher)) { + /* Waiting for cipher request completion + * before generating the An, + */ + } + an = xhdcp1x_cipher_get_mi(xhdcp1x_tx->cipher); + } + + /* Check if zero */ + if (!an) + an = 0x351F7175406A74Dull; + + return an; +} + +/** + * xhdcp1x_tx_set_keyselect: Select the aksv key + * @xhdcp1x_tx: reference to HDCP1x config structure + * @keyselect: ket selection from a group of input keys + * + * @return: 0 on success, error otherwise + */ +int xhdcp1x_tx_set_keyselect(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u8 keyselect) +{ + if (!xhdcp1x_tx) + return -EINVAL; + + return xhdcp1x_cipher_set_keyselect(xhdcp1x_tx->cipher, keyselect); +} + +/** + * xhdcp1x_tx_load_aksv: loads the local ksv to hdcp port + * @xhdcp1x_tx: reference to HDCP1X instance + * + * @return: 0 on success, error otherwise + */ +int xhdcp1x_tx_load_aksv(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 buf[XHDCP1X_PORT_SIZE_AKSV] = {0}; + + if (!xhdcp1x_tx) + return -EINVAL; + + if (xhdcp1x_cipher_load_aksv(xhdcp1x_tx->cipher, buf)) + return -EAGAIN; + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + xlnx_hdcp1x_tx_writedata(xhdcp1x_tx, + XHDMI_HDCP1X_PORT_OFFSET_AKSV, + buf, XHDCP1X_PORT_SIZE_AKSV); + else + xhdcp1x_tx->handlers.wr_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_AKSV, + buf, XHDCP1X_PORT_SIZE_AKSV); + return 0; +} + +/** + * xlnx_hdcp1x_tx_disable: This function disables the HDCP functionality + * @xhdcp1x_tx: Instanceptr is the HDCP config structure + * + * @return: no return vale + */ +void xlnx_hdcp1x_tx_disable(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + xhdcp1x_tx->is_enabled = XHDCP1X_DISABLE; + xhdcp1x_cipher_disable(xhdcp1x_tx->cipher); +} + +/** + * xlnx_hdcp1x_tx_reset: This function resets the HDCP functionality + * @xhdcp1x_tx: Instanceptr is the HDCP config structure + * + * @return: flase/other values + */ +int xlnx_hdcp1x_tx_reset(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + if (!(xhdcp1x_tx->is_enabled)) { + dev_dbg(xhdcp1x_tx->dev, "Hdcp is not started"); + return -EINVAL; + } + + xhdcp1x_tx->auth_status = XHDCP1X_TX_UNAUTHENTICATED; + + xhdcp1x_tx->curr_state = A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE; + xhdcp1x_tx->prev_state = A0_HDCP1X_TX_STATE_DETERMINE_RX_CAPABLE; + xhdcp1x_tx->state_helper = XHDCP1X_DEFAULT_INIT; + xhdcp1x_tx->tmr_cnt = 0; + xhdcp1x_tx->is_riupdate = 0; + xhdcp1x_tx->is_encryption_en = XHDCP1X_DEFAULT_INIT; + + xlnx_hdcp1x_tx_disable_encryption(xhdcp1x_tx, xhdcp1x_tx->encryption_map); + xhdcp1x_tx->encryption_map = XHDCP1X_DEFAULT_INIT; + xlnx_hdcp1x_tx_disable(xhdcp1x_tx); + + return 0; +} + +/** + * xlnx_hdcp1x_tx_enable_encryption: This function enables the encryption + * for a HDCP state machine. + * @xhdcp1x_tx: points to the HDCP config structure + * + * @return: no return value + */ +void xlnx_hdcp1x_tx_enable_encryption(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u64 stream_map = XHDCP1X_STREAM_MAP; + + if (!(xhdcp1x_tx->is_encryption_en)) { + xhdcp1x_tx->encryption_map |= stream_map; + /* Check for encryption enabled */ + if (xhdcp1x_tx->encryption_map) { + stream_map = XHDCP1X_DEFAULT_INIT; + /* Determine stream_map */ + stream_map = xhdcp1x_cipher_getencryption(xhdcp1x_tx->cipher); + + /* Check if there is something to do */ + if (stream_map != xhdcp1x_tx->encryption_map) { + /* Enable it */ + xhdcp1x_cipher_enable_encryption(xhdcp1x_tx->cipher, + xhdcp1x_tx->encryption_map); + } + } + xhdcp1x_tx->is_encryption_en = XHDCP1X_ENCRYPTION_EN; + } +} + +/** + * xlnx_hdcp1x_tx_disable_encryption: This function resets the HDCP functionality + * @xhdcp1x_tx: Instanceptr is the HDCP config structure + * @stream_map: Bit map of the streams to disable encryption. + * + * @return: flase/other values + */ +void xlnx_hdcp1x_tx_disable_encryption(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u64 stream_map) +{ + u32 status = 0; + + status = xhdcp1x_cipher_disableencryption(xhdcp1x_tx->cipher, stream_map); + if (!status) + xhdcp1x_tx->encryption_map &= ~stream_map; +} + +/** + * xlnx_hdcp1x_check_link_integrity: This function checks the link + * integrity of HDCP link. + * @xhdcp1x_tx: Instanceptr is the HDCP config structure + * + * @return: 1 if link integrity is passed, error otherwise + */ + +int xlnx_hdcp1x_check_link_integrity(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 buf[2]; + int num_tries = XHDCP1X_MAX_RETRIES, ri_check_status = 0; + + xhdcp1x_tx->is_riupdate = 0; + do { + if (xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_RO, + buf, + XHDMI_HDCP1X_PORT_SIZE_RO)) { + u16 remote_ri = 0, local_ri = 0; + + remote_ri = + xlnx_hdcp1x_buf_to_uint16(buf, + XHDMI_HDCP1X_PORT_SIZE_RO + * XHDCP1X_BYTE_IN_BITS); + + xhdcp1x_cipher_get_ri(xhdcp1x_tx->cipher, &local_ri); + if (local_ri != remote_ri) { + dev_dbg(xhdcp1x_tx->dev, "Ri checking failed\n"); + ri_check_status = 0; + } else { + ri_check_status = 1; + dev_dbg(xhdcp1x_tx->dev, "Ri checking passed\n"); + } + } else { + dev_err(xhdcp1x_tx->dev, "Ri reading failed\n"); + } + num_tries--; + } while ((ri_check_status == 0) && (num_tries > 0)); + return ri_check_status; +} + +/** + * xhdcp1x_tx_set_check_linkstate: This function enables/disables the link + * integrity, RI checking of HDCP link. + * @xhdcp1x_tx: Instanceptr is the HDCP config structure + * @is_enabled: Flag to enable/disable RI calculation + */ + +void xhdcp1x_tx_set_check_linkstate(struct xlnx_hdcp1x_config *xhdcp1x_tx, int is_enabled) +{ + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + if (is_enabled) + xhdcp1x_cipher_set_ri_update(xhdcp1x_tx->cipher, true); + else + xhdcp1x_cipher_set_ri_update(xhdcp1x_tx->cipher, false); + } +} + +int xlnx_hdcp1x_get_repeater_info(struct xlnx_hdcp1x_config *xhdcp1x_tx, u16 *info) +{ + u8 value = 0; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + if (xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BCAPS, + (void *)&value, + XHDMI_HDCP1X_PORT_SIZE_BCAPS) > 0) { + u8 ready_mask = 0; + + ready_mask = XHDMI_HDCP1X_PORT_BIT_BCAPS_REPEATER; + ready_mask |= XHDMI_HDCP1X_PORT_BIT_BCAPS_READY; + if ((value & ready_mask) == ready_mask) { + u8 buf[XHDMI_HDCP1X_PORT_SIZE_BSTATUS]; + u64 converted_value; + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BSTATUS, + buf, + XHDMI_HDCP1X_PORT_SIZE_BSTATUS); + converted_value = + xlnx_hdcp1x_buf_to_unit(buf, + BITS_PER_BYTE * sizeof(u16)); + *info = (converted_value & XHDMI_HDCP1X_PORT_BINFO_VALUE); + return 1; + } + } + } else { + if (xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BCAPS, + (void *)&value, 1) > 0) { + if ((value & XHDCP1X_PORT_BIT_BCAPS_REPEATER) != 0) { + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BSTATUS, + &value, 1); + if ((value & XHDCP1X_PORT_BIT_BSTATUS_READY) != 0) { + u8 buf[XHDMI_HDCP1X_PORT_SIZE_BSTATUS]; + u16 binfo = 0; + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BINFO, + buf, + XHDCP1X_PORT_SIZE_BINFO); + binfo = xlnx_hdcp1x_buf_to_unit(buf, + BITS_PER_BYTE * + sizeof(u16)); + *info = (binfo & XHDCP1X_PORT_BINFO_VALUE); + + return 1; + } + } + } + } + + return 0; +} + +int xlnx_hdcp1x_gettopology_maxcascadeexceeded(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 value = 0; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BSTATUS, + (void *)&value, + XHDMI_HDCP1X_PORT_SIZE_BSTATUS); + return ((value & XHDMI_HDCP1X_PORT_BSTATUS_BIT_DEPTH_ERR) ? 1 : 0); + } + + return ((value & XHDCP1X_PORT_BINFO_BIT_DEPTH_ERR) ? 1 : 0); +} + +int xlnx_hdcp1x_gettopology_maxdevsexceeded(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 value = 0; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BSTATUS, + (void *)&value, + XHDMI_HDCP1X_PORT_SIZE_BSTATUS); + return ((value & XHDMI_HDCP1X_PORT_BSTATUS_BIT_DEV_CNT_ERR) ? 1 : 0); + } + + return ((value & XHDCP1X_PORT_BINFO_BIT_DEV_CNT_ERR) ? 1 : 0); +} + +enum hdcp1x_tx_state xlnx_hdcp1x_tx_wait_for_ready(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u16 repeater_info = 0; + + if (!xhdcp1x_tx->xhdcp1x_internal_timer.timer_expired) + return A6_HDCP1X_TX_STATE_WAIT_FOR_READY; + + xhdcp1x_tx->tmr_cnt++; + if (xhdcp1x_tx->tmr_cnt > XHDMI_HDCP1X_READY_TIMEOUT) + return H0_HDCP1X_TX_STATE_DISABLED_NO_RX_ATTACHED; + + if (!xlnx_hdcp1x_get_repeater_info(xhdcp1x_tx, &repeater_info)) { + xlnx_hdcp1x_tx_start_timer(xhdcp1x_tx, XHDMI_HDCP1X_WAIT_FOR_READY_TIMEOUT, 0); + + return A6_HDCP1X_TX_STATE_WAIT_FOR_READY; + } + xhdcp1x_tx->state_helper = repeater_info; + xhdcp1x_tx->tmr_cnt = 0; + + return A7_HDCP1X_TX_STATE_READ_KSV_LIST; +} + +static u64 xlnx_hdcp1x_buf_to_u64(u8 *buf, u64 size) +{ + u64 buff_to_int = 0; + + if ((size) > 0) { + int byte; + + for (byte = (((size) - 1) >> 3); byte >= 0; byte--) { + buff_to_int <<= XHDCP1X_BYTE_IN_BITS; + buff_to_int |= buf[byte]; + } + } + + return buff_to_int; +} + +int xlnx_hdcp1x_tx_validate_ksv_list(struct xlnx_hdcp1x_config *xhdcp1x_tx, u16 repeater_info) +{ + struct xlnx_sha1_context sha1_context; + u8 buf[DRM_HDCP_KSV_LEN * XHDCP1X_PORT_SIZE_BKSV]; + u8 ksv_list_holder[XHDMI_HDCP1X_PORT_MAX_DEV_CNT * XHDCP1X_PORT_SIZE_BKSV]; + int num_to_read = 0; + int ksv_count = 0, byte_count = 0; + int ret = 0; + unsigned int ksv_list_size = 0; + u64 value = 0, buf_read_ksv_count = 0, mo = 0, remote_ksv; + u8 sha_result[SHA1_HASH_SIZE]; + u8 bksv[XHDCP1X_PORT_SIZE_BKSV]; + + memset(ksv_list_holder, 0, (XHDMI_HDCP1X_PORT_MAX_DEV_CNT * XHDCP1X_PORT_SIZE_BKSV)); + + memset(buf, 0, DRM_HDCP_KSV_LEN * XHDCP1X_PORT_SIZE_BKSV); + + xlnx_sha1_reset(&sha1_context); + + repeater_info = xhdcp1x_tx->state_helper; + num_to_read = ((repeater_info & XHDMI_HDCP1X_PORT_MAX_DEV_CNT) * DRM_HDCP_KSV_LEN); + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + if (xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_OFFSET_KSVFIFO, + ksv_list_holder, num_to_read)) { + xlnx_sha1_input(&sha1_context, ksv_list_holder, num_to_read); + + while (byte_count < num_to_read) { + if ((byte_count + 1) % DRM_HDCP_KSV_LEN == 0) { + value = xlnx_hdcp1x_buf_to_unit((ksv_list_holder + + ((((byte_count + 1) + / XHDCP1X_PORT_SIZE_BKSV) + - 1) + * XHDCP1X_PORT_SIZE_BKSV)), + XHDCP1X_PORT_SIZE_BKSV * + BITS_PER_BYTE); + + if (!xlnx_hdcp1x_is_ksvvalid(value)) + return false; + + xhdcp1x_tx->repeatervalues.ksvlist[ksv_count++] = value; + value = 0; + } + byte_count++; + } + } + } else { + unsigned int ksv_list_byte_count = 0; + + byte_count = (num_to_read / DRM_HDCP_KSV_LEN); + ksv_list_size = byte_count; + do { + int total_bytes = XHDCP1X_PORT_SIZE_KSVFIFO; + int min_bytes_to_read = XHDCP1X_PORT_MIN_BYTES; + + if (total_bytes > num_to_read) + total_bytes = num_to_read; + + if (min_bytes_to_read > byte_count) + min_bytes_to_read = byte_count; + + ret = xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_KSVFIFO, + buf, total_bytes); + if (!ret) + return false; + + xlnx_sha1_input(&sha1_context, buf, total_bytes); + while (buf_read_ksv_count < total_bytes) { + ksv_list_holder[ksv_list_byte_count++] = + buf[buf_read_ksv_count]; + buf_read_ksv_count++; + } + num_to_read -= total_bytes; + byte_count -= min_bytes_to_read; + + } while (num_to_read > 0); + } + + /* Insert repeater_info into the SHA-1 transform */ + buf[0] = (u8)repeater_info; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + buf[1] = (u8)(repeater_info + >> XHDMI_HDCP1X_PORT_BSTATUS_DEPTH_SHIFT); + else + buf[1] = (u8)(repeater_info >> XHDCP1X_PORT_BINFO_DEPTH_SHIFT); + + xlnx_sha1_input(&sha1_context, buf, 2); + + /* Insert the mo into the SHA-1 transform */ + mo = xhdcp1x_cipher_get_mo(xhdcp1x_tx->cipher); + xlnx_hdcp1x_uint_to_buf(buf, mo, XHDCP1X_BYTE_IN_BITS * BITS_PER_BYTE); + + xlnx_sha1_input(&sha1_context, buf, BITS_PER_BYTE); + + /* Finalize the SHA-1 result and confirm success */ + if (xlnx_sha1_result(&sha1_context, sha_result) == XLNX_SHA_SUCCESS) { + u64 offset = 0; + const u8 *sha1_buf = sha_result; + int num_iterations = (SHA1_HASH_SIZE >> 2); + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + offset = XHDMI_HDCP1X_PORT_OFFSET_VH0; + else + offset = XHDCP1X_PORT_OFFSET_VH0; + + do { + u32 calc_calue = 0; + u32 read_value = 0; + + /* Determine calc_calue */ + calc_calue = *sha1_buf++; + calc_calue <<= BITS_PER_BYTE; + calc_calue |= *sha1_buf++; + calc_calue <<= BITS_PER_BYTE; + calc_calue |= *sha1_buf++; + calc_calue <<= BITS_PER_BYTE; + calc_calue |= *sha1_buf++; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + offset = XHDMI_HDCP1X_PORT_OFFSET_VH0; + + else + offset = XHDCP1X_PORT_OFFSET_VH0; + + ret = + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + offset, buf, + XHDCP1X_PORT_SIZE_VH0); + + if (!ret) { + dev_err(xhdcp1x_tx->dev, "Unable to read V"); + return false; + } + memcpy(&xhdcp1x_tx->repeatervalues.v[offset - XHDMI_HDCP1X_PORT_OFFSET_VH0], + buf, XHDCP1X_PORT_SIZE_VH0); + read_value = xlnx_hdcp1x_buf_to_unit(buf, + BITS_PER_BYTE * XHDCP1X_PORT_SIZE_VH0); + if (calc_calue != read_value) { + dev_err(xhdcp1x_tx->dev, "V` Ksv's miss match"); + return false; + } + offset += XHDCP1X_PORT_SIZE_VH0; + num_iterations--; + } while (num_iterations > 0); + } else { + dev_err(xhdcp1x_tx->dev, "SHA mismatch Occurred"); + return false; + } + if (xhdcp1x_tx->is_repeater) { + if (xhdcp1x_tx->protocol == XHDCP1X_TX_DP) { + u64 val = 0; + u32 this_ksv = 0; + + while (this_ksv < ksv_list_size) { + val = xlnx_hdcp1x_buf_to_u64((ksv_list_holder + + (this_ksv * + XHDCP1X_PORT_SIZE_BKSV)), + XHDCP1X_PORT_SIZE_BKSV * + BITS_PER_BYTE); + if (!(val)) { + this_ksv++; + continue; + } + xhdcp1x_tx->repeatervalues.ksvlist[ksv_count++] = val; + + val = 0; + this_ksv++; + } + } + + memset(bksv, 0, XHDCP1X_PORT_SIZE_BKSV); + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BKSV, + bksv, + XHDMI_HDCP1X_PORT_SIZE_BKSV); + else + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BKSV, + bksv, XHDCP1X_PORT_SIZE_BKSV); + + /* Determine theremote_ksv */ + remote_ksv = xlnx_hdcp1x_buf_to_unit(bksv, + XHDCP1X_PORT_SIZE_BKSV * BITS_PER_BYTE); + /* Check for invalid */ + if (!xlnx_hdcp1x_is_ksvvalid(remote_ksv)) { + dev_dbg(xhdcp1x_tx->dev, "Invalid Bksv reads"); + return 0; + } + xhdcp1x_tx->repeatervalues.ksvlist[ksv_count] = remote_ksv; + } + return true; +} + +int xlnx_hdcp1x_setrepeaterinfo(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u8 bksv[BITS_PER_BYTE]; + u32 ksv_count = 0, buf; + + if (xhdcp1x_tx->is_repeater) { + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) { + /* Set the SHA1 Hash value */ + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_VH0, + (void *)&buf, + XHDMI_HDCP1X_PORT_SIZE_VH0); + + /* V'H0 */ + xhdcp1x_tx->repeatervalues.v[0] = (u16)buf; + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_VH1, + (void *)&buf, + XHDMI_HDCP1X_PORT_SIZE_VH1); + + /* V'H1 */ + xhdcp1x_tx->repeatervalues.v[1] = (u16)buf; + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_VH2, + (void *)&buf, + XHDMI_HDCP1X_PORT_SIZE_VH2); + + /* V'H2 */ + xhdcp1x_tx->repeatervalues.v[2] = (u16)buf; + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_VH3, + (void *)&buf, + XHDMI_HDCP1X_PORT_SIZE_VH3); + + /* V'H3 */ + xhdcp1x_tx->repeatervalues.v[3] = (u16)buf; + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_VH4, + (void *)&buf, + XHDMI_HDCP1X_PORT_SIZE_VH4); + + /* V'H4 */ + xhdcp1x_tx->repeatervalues.v[4] = (u16)buf; + /* Copy the Depth read from the downstream HDCP device */ + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BSTATUS, + (void *)&buf, + XHDMI_HDCP1X_PORT_SIZE_BSTATUS); + + xhdcp1x_tx->repeatervalues.depth = ((buf & + XHDCP1X_PORT_BINFO_DEPTH_MASK) >> + BITS_PER_BYTE); + xhdcp1x_tx->repeatervalues.device_count = (buf & + XHDCP1X_PORT_BINFO_DEV_CNT_MASK); + xhdcp1x_tx->repeatervalues.device_count++; + } else { + u16 repeater_info; + + repeater_info = (u16)xhdcp1x_tx->state_helper; + + xhdcp1x_tx->repeatervalues.depth = ((repeater_info & + XHDCP1X_PORT_BINFO_DEPTH_MASK) >> + BITS_PER_BYTE); + xhdcp1x_tx->repeatervalues.device_count = repeater_info & + XHDCP1X_PORT_BINFO_DEV_CNT_MASK; + xhdcp1x_tx->repeatervalues.device_count++; + } + } else { + u64 remote_ksv = 0; + + xhdcp1x_tx->repeatervalues.depth = 0; + + xhdcp1x_tx->repeatervalues.device_count = 1; + + if (xhdcp1x_tx->protocol != XHDCP1X_TX_DP) + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BKSV, + bksv, + XHDMI_HDCP1X_PORT_SIZE_BKSV); + else + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDCP1X_PORT_OFFSET_BKSV, + bksv, XHDCP1X_PORT_SIZE_BKSV); + + remote_ksv = xlnx_hdcp1x_buf_to_uint16(bksv, + XHDCP1X_PORT_SIZE_BKSV * BITS_PER_BYTE); + + if (!xlnx_hdcp1x_is_ksvvalid(remote_ksv)) { + dev_dbg(xhdcp1x_tx->dev, "bksv invalid"); + return 0; + } + xhdcp1x_tx->repeatervalues.ksvlist[ksv_count++] = remote_ksv; + } + + return 1; +} + +int xlnx_hdcp1x_tx_read_ksv_list(struct xlnx_hdcp1x_config *xhdcp1x_tx) +{ + u32 num_attempts = 3; + u32 ksv_list_valid = 0; + u16 repeater_info; + u8 bksv[BITS_PER_BYTE]; + + repeater_info = (xhdcp1x_tx->state_helper & XHDMI_HDCP1X_PORT_BINFO_VALUE); + + if ((!xlnx_hdcp1x_gettopology_maxcascadeexceeded(xhdcp1x_tx)) && + (!xlnx_hdcp1x_gettopology_maxdevsexceeded(xhdcp1x_tx))) { + dev_dbg(xhdcp1x_tx->dev, "Received Correct topology from Downstream Devices"); + } else { + u64 remote_ksv = 0; + + dev_dbg(xhdcp1x_tx->dev, "Received Incorrect topology from Downstream Devices"); + xlnx_hdcp1x_tx_disable_encryption(xhdcp1x_tx, xhdcp1x_tx->encryption_map); + xhdcp1x_tx->repeatervalues.depth = + ((repeater_info & XHDCP1X_PORT_BINFO_DEPTH_MASK) >> + XHDMI_HDCP1X_PORT_BSTATUS_DEPTH_SHIFT); + xhdcp1x_tx->repeatervalues.device_count = + (repeater_info & + XHDMI_HDCP1X_PORT_BSTATUS_DEV_CNT_MASK); + + xhdcp1x_tx->handlers.rd_handler(xhdcp1x_tx->interface_ref, + XHDMI_HDCP1X_PORT_OFFSET_BKSV, + bksv, XHDCP1X_PORT_SIZE_BKSV); + remote_ksv = xlnx_hdcp1x_buf_to_uint16(bksv, + XHDCP1X_PORT_SIZE_BKSV * BITS_PER_BYTE); + + if (!xlnx_hdcp1x_is_ksvvalid(remote_ksv)) + xhdcp1x_tx->repeatervalues.ksvlist[0] = remote_ksv; + else + xhdcp1x_tx->repeatervalues.ksvlist[0] = 0x0; + + memset(xhdcp1x_tx->repeatervalues.v, 0x0, sizeof(u32) * XHDCP1X_PORT_SIZE_BKSV); + + xhdcp1x_tx->repeatervalues.hdcp14_propagatetopo_errupstream = true; + + if ((repeater_info & 0x800) != 0) + dev_dbg(xhdcp1x_tx->dev, "Max Cascade Exceeded"); + else + dev_dbg(xhdcp1x_tx->dev, "Max Devicec Exceeded"); + + return 0; + } + + do { + ksv_list_valid = xlnx_hdcp1x_tx_validate_ksv_list(xhdcp1x_tx, repeater_info); + num_attempts--; + } while ((num_attempts > 0) && (!ksv_list_valid)); + + if (ksv_list_valid) { + if (xhdcp1x_tx->is_repeater) + xlnx_hdcp1x_setrepeaterinfo(xhdcp1x_tx); + xhdcp1x_tx->downstreamready = 1; + return 1; + } + + return 0; +} + +void xlnx_hdcp1x_tx_timer_init(struct xlnx_hdcp1x_config *xhdcp1x_tx, + struct xlnx_hdcp_timer_config *tmr_cntrl) +{ + xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr = *tmr_cntrl; + + xlnx_hdcp_tmrcntr_set_options(&xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr, + 0, + XTC_INT_MODE_OPTION | XTC_DOWN_COUNT_OPTION); +} + +void xlnx_hdcp1x_tx_start_timer(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u32 timeout, u8 reason_id) +{ + u32 ticks = (u32)(xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr.hw_config.sys_clock_freq + / XHDCP1X_TX_CLKDIV_MHZ) * timeout * XHDCP1X_TX_CLKDIV_HZ; + + xlnx_hdcp_tmrcntr_stop(&xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr, 0); + + xhdcp1x_tx->xhdcp1x_internal_timer.timer_expired = (0); + xhdcp1x_tx->xhdcp1x_internal_timer.reason_id = reason_id; + xhdcp1x_tx->xhdcp1x_internal_timer.initial_ticks = ticks; + + xlnx_hdcp_tmrcntr_set_reset_value(&xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr, + 0, ticks); + xlnx_hdcp_tmrcntr_start(&xhdcp1x_tx->xhdcp1x_internal_timer.tmr_ctr, 0); +} + +void xlnx_hdcp1x_tx_timer_handler(void *callbackref, u8 tmr_cnt_number) +{ + struct xlnx_hdcp1x_config *xhdcp1x_tx = (struct xlnx_hdcp1x_config *)callbackref; + + if (tmr_cnt_number == XTC_TIMER_1) + return; + + xhdcp1x_tx->xhdcp1x_internal_timer.timer_expired = 1; +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp1x_tx.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp1x_tx.h @@ -0,0 +1,362 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx Specific HDCP1X driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Katta Dhanunjanrao + * + */ +#include +#include +#include +#include +#include +#include "xhdcp1x_tx.h" + +/* Basic configuration enable/disable list of macros */ +#define XHDCP1X_ENABLE 1 +#define XHDCP1X_DISABLE 0 +#define XHDCP1X_DEFAULT_INIT 0 +#define XHDCP1X_ENCRYPTION_EN 1 +#define XHDCP1X_ENCRYPTION_DISABLE 0 +#define XHDCP1X_MAX_RETRIES 3 +#define XHDCP1X_BYTE_IN_BITS 8 +#define XHDCP1X_REMOTE_BKSV_SIZE 5 +#define XHDCP1X_REMOTE_INFO_BCAPS_VAL 1 +#define XHDCP1X_REMOTE_RO_SIZE 2 +#define XHDCP1X_KSV_NUM_OF_1S 20 +#define XHDCP1X_RO_AVILABLE_DELAY 100 +#define XHDCP1X_VERSION (0x01u) +#define XHDCP1X_STREAM_MAP (0x01) +#define XHDCP1X_BUF_OFFSET_LEN (0x100) +#define XHDCP1X_TX_REVOCLIST_MAX_DEVICES 944 +#define XHDCP1X_TX_ENCRYPTION_KEY_SIZE 336 +#define XHDCP1X_PORT_MIN_BYTES 3 +/* These constants specify the offsets for the various fields and/or + * attributes within the hdcp port + */ +#define XDPTX_HDCP1X_DPCD_OFFSET 0x68000 +#define XHDCP1X_PORT_OFFSET_BKSV (0x00 + XDPTX_HDCP1X_DPCD_OFFSET) /* Bksv Offset */ +#define XHDCP1X_PORT_OFFSET_RO (0x05 + XDPTX_HDCP1X_DPCD_OFFSET) /* R0' Offset */ +#define XHDCP1X_PORT_OFFSET_AKSV (0x07 + XDPTX_HDCP1X_DPCD_OFFSET) /* Aksv Offset */ +#define XHDCP1X_PORT_OFFSET_AN (0x0C + XDPTX_HDCP1X_DPCD_OFFSET) /* An Offset */ +#define XHDCP1X_PORT_OFFSET_VH0 (0x14 + XDPTX_HDCP1X_DPCD_OFFSET) /* V'.H0 Offset */ +#define XHDCP1X_PORT_OFFSET_VH1 (0x18 + XDPTX_HDCP1X_DPCD_OFFSET) /* V'.H1 Offset */ +#define XHDCP1X_PORT_OFFSET_VH2 (0x1C + XDPTX_HDCP1X_DPCD_OFFSET) /* V'.H2 Offset */ +#define XHDCP1X_PORT_OFFSET_VH3 (0x20 + XDPTX_HDCP1X_DPCD_OFFSET) /* V'.H3 Offset */ +#define XHDCP1X_PORT_OFFSET_VH4 (0x24 + XDPTX_HDCP1X_DPCD_OFFSET) /* V'.H4 Offset */ +#define XHDCP1X_PORT_OFFSET_BCAPS (0x28 + XDPTX_HDCP1X_DPCD_OFFSET) /* Bcaps Offset */ +#define XHDCP1X_PORT_OFFSET_BSTATUS (0x29 + XDPTX_HDCP1X_DPCD_OFFSET) /* Bstatus Offset */ +#define XHDCP1X_PORT_OFFSET_BINFO (0x2A + XDPTX_HDCP1X_DPCD_OFFSET) /* Binfo Offset */ +#define XHDCP1X_PORT_OFFSET_KSVFIFO (0x2C + XDPTX_HDCP1X_DPCD_OFFSET) /* KSV FIFO Offset */ +#define XHDCP1X_PORT_OFFSET_AINFO (0x3B + XDPTX_HDCP1X_DPCD_OFFSET) /* Ainfo Offset */ +#define XHDCP1X_PORT_OFFSET_DBG (0xC0 + XDPTX_HDCP1X_DPCD_OFFSET) /* Debug Space Offset */ +#define XHDCP1X_PORT_HDCP_RESET_KSV (0xD0 + XDPTX_HDCP1X_DPCD_OFFSET) /* KSV FIFO Read pointer + * reset Offset + */ +/* + * These constants specify the sizes for the various fields and/or + * attributes within the hdcp port for HDMI Interface + */ +#define XHDCP1X_PORT_SIZE_BKSV (0x05u) /* Bksv Size */ +#define XHDCP1X_PORT_SIZE_RO (0x02u) /* R0' Size */ +#define XHDCP1X_PORT_SIZE_AKSV (0x05u) /* Aksv Size */ +#define XHDCP1X_PORT_SIZE_AN (0x08u) /* An Size */ +#define XHDCP1X_PORT_SIZE_VH0 (0x04u) /* V'.H0 Size */ +#define XHDCP1X_PORT_SIZE_VH1 (0x04u) /* V'.H1 Size */ +#define XHDCP1X_PORT_SIZE_VH2 (0x04u) /* V'.H2 Size */ +#define XHDCP1X_PORT_SIZE_VH3 (0x04u) /* V'.H3 Size */ +#define XHDCP1X_PORT_SIZE_VH4 (0x04u) /* V'.H4 Size */ +#define XHDCP1X_PORT_SIZE_BCAPS (0x01u) /* Bcaps Size */ +#define XHDCP1X_PORT_SIZE_BSTATUS (0x01u) /* Bstatus Size */ +#define XHDCP1X_PORT_SIZE_BINFO (0x02u) /* Binfo Size */ +#define XHDCP1X_PORT_SIZE_KSVFIFO (0x0Fu) /* KSV FIFO Size */ +#define XHDCP1X_PORT_SIZE_AINFO (0x01u) /* Ainfo Offset */ +#define XHDCP1X_PORT_SIZE_DBG (0x40u) /* Debug Space Size */ +#define XHDCP1X_PORT_SIZE_HDCP_RESET_KSV (0x40u) /* KSV FIFO pointer reset Size */ +/* + * These constants specify the bit definitions within the various fields + * and/or attributes within the hdcp port + */ +#define XHDCP1X_PORT_BIT_BSTATUS_READY BIT(0) /* BStatus Ready Mask */ +#define XHDCP1X_PORT_BIT_BSTATUS_RO_AVAILABLE BIT(1) /* BStatus Ro available Mask */ +#define XHDCP1X_PORT_BIT_BSTATUS_LINK_FAILURE BIT(2) /* BStatus Link Failure Mask */ +#define XHDCP1X_PORT_BIT_BSTATUS_REAUTH_REQUEST BIT(3) /* BStatus Reauth Request Mask */ +#define XHDCP1X_PORT_BIT_BCAPS_HDCP_CAPABLE BIT(0) /* BCaps HDCP Capable Mask */ +#define XHDCP1X_PORT_BIT_BCAPS_REPEATER BIT(1) /* BCaps HDCP Repeater Mask */ +#define XHDCP1X_PORT_BIT_AINFO_REAUTH_ENABLE_IRQ BIT(0) /**< Ainfo Reauth Enable Mask */ +#define XHDCP1X_PORT_HDCP_RESET_KSV_RST BIT(0) /* KSV FIFO pointer Reset Mask */ +#define XHDCP1X_PORT_BINFO_BIT_DEV_CNT_ERR BIT(7) /* BInfo Device Count Error Mask */ +/* BInfo Device Count for No Error Mask */ +#define XHDCP1X_PORT_BINFO_BIT_DEV_CNT_NO_ERR (0u << 7) +#define XHDCP1X_PORT_BINFO_DEV_CNT_MASK (0x7F) /* BInfo Device Count Error Mask */ +#define XHDCP1X_PORT_BINFO_DEPTH_MASK 0x0700 /* BIndo Depth Mask */ +#define XHDCP1X_PORT_BINFO_BIT_DEPTH_ERR BIT(11) /* BInfo Depth Error Mask */ +/* BInfo Depth Error for No Error Mask */ +#define XHDCP1X_PORT_BINFO_BIT_DEPTH_NO_ERR (0u << 11) +#define XHDCP1X_PORT_BINFO_DEV_CNT_ERR_SHIFT (7) /* BStatus Device Count Error Shift Mask */ +#define XHDCP1X_PORT_BINFO_DEPTH_ERR_SHIFT (11) /* BStatus Depth Error Shift Mask */ +#define XHDCP1X_PORT_BINFO_DEPTH_SHIFT (8) /* BInfo Device Count Error Mask */ +#define XHDCP1X_PORT_BINFO_VALUE GENMASK(12, 0) +/* + * These constants specify the sizes for the various fields and/or + * attributes within the hdcp port for HDMI interface + */ +#define XHDMI_HDCP1X_PORT_SIZE_BKSV (0x05u) /**< Bksv Size */ +#define XHDMI_HDCP1X_PORT_SIZE_RO (0x02u) /**< Ri' Size */ +#define XHDMI_HDCP1X_PORT_SIZE_PJ (0x01u) /**< Pj' Size */ +#define XHDMI_HDCP1X_PORT_SIZE_AKSV (0x05u) /**< Aksv Size */ +#define XHDMI_HDCP1X_PORT_SIZE_AINFO (0x01u) /**< Ainfo Size */ +#define XHDMI_HDCP1X_PORT_SIZE_AN (0x08u) /**< An Size */ +#define XHDMI_HDCP1X_PORT_SIZE_VH0 (0x04u) /**< V'.H0 Size */ +#define XHDMI_HDCP1X_PORT_SIZE_VH1 (0x04u) /**< V'.H1 Size */ +#define XHDMI_HDCP1X_PORT_SIZE_VH2 (0x04u) /**< V'.H2 Size */ +#define XHDMI_HDCP1X_PORT_SIZE_VH3 (0x04u) /**< V'.H3 Size */ +#define XHDMI_HDCP1X_PORT_SIZE_VH4 (0x04u) /**< V'.H4 Size */ +#define XHDMI_HDCP1X_PORT_SIZE_BCAPS (0x01u) /**< Bcaps Size */ +#define XHDMI_HDCP1X_PORT_SIZE_BSTATUS (0x02u) /**< Bstatus Size */ +#define XHDMI_HDCP1X_PORT_SIZE_KSVFIFO (0x01u) /**< KSV FIFO Size */ +#define XHDMI_HDCP1X_PORT_SIZE_DBG (0xC0u) /**< Debug Space Size */ +/* + * These constants specify the offsets for the various fields and/or + * attributes within the hdcp port for HDMI interface + */ +#define XHDMI_HDCP1X_PORT_OFFSET_BKSV (0x00u) /**< Bksv Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_RO (0x08u) /**< Ri'/Ro' Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_PJ (0x0Au) /**< Pj' Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_AKSV (0x10u) /**< Aksv Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_AINFO (0x15u) /**< Ainfo Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_AN (0x18u) /**< An Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_VH0 (0x20u) /**< V'.H0 Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_VH1 (0x24u) /**< V'.H1 Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_VH2 (0x28u) /**< V'.H2 Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_VH3 (0x2Cu) /**< V'.H3 Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_VH4 (0x30u) /**< V'.H4 Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_BCAPS (0x40u) /**< Bcaps Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_BSTATUS (0x41u) /**< Bstatus Offset */ +#define XHDMI_HDCP1X_OFFSET_KSVFIFO (0x43u) /**< KSV FIFO Offset */ +#define XHDMI_HDCP1X_PORT_OFFSET_DBG (0xC0u) /**< Debug Space Offset */ + +#define XHDMI_HDCP1X_PORT_BIT_BSTATUS_HDMI_MODE BIT(12) +#define XHDMI_HDCP1X_PORT_BIT_BCAPS_FAST_REAUTH BIT(0) +#define XHDMI_HDCP1X_PORT_BIT_BCAPS_1d1_FEATURES BIT(1) +#define XHDMI_HDCP1X_PORT_BIT_BCAPS_FAST BIT(4) +#define XHDMI_HDCP1X_PORT_BIT_BCAPS_READY BIT(5) +#define XHDMI_HDCP1X_PORT_BIT_BCAPS_REPEATER BIT(6) +#define XHDMI_HDCP1X_PORT_BIT_BCAPS_HDMI BIT(7) +#define XHDMI_HDCP1X_PORT_BIT_AINFO_ENABLE_1d1_FEATURES BIT(1) +#define XHDMI_HDCP1X_PORT_BSTATUS_BIT_DEV_CNT_ERR BIT(7) +#define XHDMI_HDCP1X_PORT_BSTATUS_BIT_DEV_CNT_NO_ERR (0u << 7) +#define XHDMI_HDCP1X_PORT_BSTATUS_DEV_CNT_MASK (0x7F) +#define XHDMI_HDCP1X_PORT_BSTATUS_BIT_DEPTH_ERR BIT(11) +#define XHDMI_HDCP1X_PORT_BSTATUS_BIT_DEPTH_NO_ERR (0u << 11) +#define XHDMI_HDCP1X_PORT_BSTATUS_DEV_CNT_ERR_SHIFT (7) +#define XHDMI_HDCP1X_PORT_BSTATUS_DEPTH_ERR_SHIFT (11) +#define XHDMI_HDCP1X_PORT_BSTATUS_DEPTH_SHIFT (8) +#define XHDMI_HDCP1X_PORT_BINFO_VALUE GENMASK(13, 0) +#define XHDMI_HDCP1X_PORT_MAX_DEV_CNT (0x7F) +#define XHDMI_HDCP1X_READY_TIMEOUT 25 +#define XHDMI_HDCP1X_WAIT_FOR_READY_TIMEOUT 200 +#define XHDMI_HDCP1X_WAIT_FOR_ACTIVE_RECEIVER 2000 +#define XHDCP1X_TX_CLKDIV_MHZ 1000000 +#define XHDCP1X_TX_CLKDIV_HZ 1000 + +/* + * struct xhdcp1x_tx_callbacks - This structure contains the callback handlers. + * @rd_handler: The DP/HDMI read handler call for the aux channels + * @wr_handler: The DP/HDMI write handler call for the aux channels + * @notify_handler: The DP/HDMI notify handler call for the aux channels + */ +struct xhdcp1x_tx_callbacks { + int (*rd_handler)(void *interface_ref, u32 offset, u8 *buf, u32 size); + int (*wr_handler)(void *interface_ref, u32 offset, u8 *buf, u32 size); + void (*notify_handler)(void *interface_ref, u32 notification); +}; + +enum xlnx_hdcp1x_tx_callback_type { + XHDCP1X_TX_HANDLER_AUX_READ = 0, + XHDCP1X_TX_HANDLER_AUX_WRITE = 1, + XHDCP1X_TX_HANDLER_HDCP_STATUS = 2, + XHDCP1X_TX_HANDLER_INVALID = 3 +}; + +enum xhdcp1x_tx_authtype { + XHDCP1X_TX_AUTHENTICATED = 0, + XHDCP1X_TX_UNAUTHENTICATED = 1, + XHDCP1X_TX_INCOMPATIBLE_RX = 2, + XHDCP1X_TX_AUTHENTICATION_BUSY = 3, + XHDCP1X_TX_REAUTHENTICATE_REQUESTED = 4, + XHDCP1X_TX_DEVICE_IS_REVOKED = 5, +}; + +enum xhdcp1x_tx_protocol { + XHDCP1X_TX_DP = 0, + XHDCP1X_TX_HDMI = 1, +}; + +/* + * struct hdcp1x_tx_revoclist - This structure contains the HDCP + * keys revocation list information + * @rcvid: The array contains the revocation keys list of information + * @num_of_devices: Number of devices in the revocated list count + */ +struct hdcp1x_tx_revoclist { + u8 rcvid[XHDCP1X_TX_REVOCLIST_MAX_DEVICES][DRM_HDCP_KSV_LEN]; + u32 num_of_devices; +}; + +/* + * struct xhdcp1x_repeater_exchange - This structure contains an instance of the HDCP + * Repeater values to exchanged between HDCP Tx and HDCP Rx + * @v[5]: The 20 byte value of SHA1 hash, v'h0,v'h1,v'h2,v'h3,v'h4 + * read from downstream repeater. + * @ksvlist[32]: An array of 32 elements each of 64 bits to store the KSVs + * for the KSV FIFO + * @depth: depeth of downstream topology + * @device_count: Number of downstream devices attached to the repeater + * @hdcp14_propagatetopo_errupstream: propagate the topology error to upstream + */ +struct xhdcp1x_repeater_exchange { + u32 v[DRM_HDCP_KSV_LEN]; + u64 ksvlist[HDCP_2_2_MAX_DEVICE_COUNT + 1]; + u8 depth; + u8 device_count; + u8 hdcp14_propagatetopo_errupstream; +}; + +/* + * struct xhdcp1x_tx_status - This structure contains Hdcp1x driver + * status information fields + * @auth_failed: Authentication failures count + * @auth_passed: Authentication passed status/count + * @reauth_requested: Re-Authentication request if any link failures..etc + * @read_failure: remote device read failures + * @link_checkpassed: Link verification that is passed + * @link_checkfailed: Link verification that is failure + * + */ +struct xhdcp1x_tx_status { + u32 auth_status; + u32 auth_failed; + u32 auth_passed; + u32 reauth_requested; + u32 read_failure; + u32 link_checkpassed; + u32 link_checkfailed; +}; + +/* + * struct xhdcp1x_tx_internal_timer - Current state and data used for internal timer + * @tmr_ctr: hardware timer configuration structure + * @initial_ticks: Keep track of the start value of the timer. + * @timer_expired: Expiration flag set when the hardware timer has interrupted. + * @reason_id: Keep track of why the timer was started (message or status checking) + */ +struct xhdcp1x_tx_internal_timer { + struct xlnx_hdcp_timer_config tmr_ctr; + u32 initial_ticks; + u8 timer_expired; + u8 reason_id; +}; + +/* + * struct xlnx_hdcp1x_config - This structure contains Hdcp1x driver + * configuration information + * @dev: device information + * @handlers: Callback handlers + * @sm_work: state machine worker + * @curr_state: current authentication state + * @prev_sate: Previous Authentication State + * @repeatervalues: The downstream repeater capabilities + * @stats: authentication status + * @hdcp1x_keymgmt_base: Key management base address + * @cipher: Pointer to cipher driver instance + * @interface_ref: Pointer to interface(DP/HDMI) driver instance + * @interface_base: Pointer to instance iomem base + * @pending_events: Evenets that are set by interface driver + * @downstreamready: To check the downstream device status ready or not + * @is_repeater: says whether downstream is repeater or receiver + * @hdcp1x_key_availble: The KMS block has key exists or not. + * @lane_count: number of lanes data to be encrypted + * @hdcp1x_key: hdcp1x key pointer + * @auth_status: first stage authentication status + * @keyinit: Key Management Block with key initiliazed properly or not + * @is_encryption_en: Encryption enbalemnet is done or not + * @is_cipher: is cipher init is done or not + * @state_helper: to store the An value temp basis + * @encryption_map: To check the encryption progress + * + */ +struct xlnx_hdcp1x_config { + struct device *dev; + struct xhdcp1x_tx_callbacks handlers; + struct hdcp1x_tx_revoclist xhdcp1x_revoc_list; + struct xhdcp1x_tx_internal_timer xhdcp1x_internal_timer; + struct delayed_work sm_work; + enum hdcp1x_tx_state curr_state; + enum hdcp1x_tx_state prev_state; + struct xhdcp1x_repeater_exchange repeatervalues; + struct xhdcp1x_tx_status stats; + struct regmap *hdcp1x_keymgmt_base; + void *cipher; + void *interface_ref; + void __iomem *interface_base; + u32 pending_events; + u32 downstreamready; + u32 tmr_cnt; + bool is_repeater; + bool hdcp1x_key_available; + u8 lane_count; + u8 *hdcp1x_key; + u8 auth_status; + u8 keyinit; + u8 is_encryption_en; + u8 is_enabled; + u8 is_cipher; + u8 is_hdmi; + u8 protocol; + u8 is_riupdate; + u64 state_helper; + u64 encryption_map; + u8 *xlnx_hdcp1x_key; +}; + +void xlnx_start_hdcp1x_engine(struct xlnx_hdcp1x_config *xhdcp1x_tx); +bool xlnx_hdcp1x_tx_init(struct xlnx_hdcp1x_config *xhdcp1x_tx, bool is_repeater); +int xlnx_hdcp1x_task_monitor(struct xlnx_hdcp1x_config *xhdcp1x_tx); +bool xlnx_hdcp1x_downstream_capbility(struct xlnx_hdcp1x_config *xhdcp1x_tx); +bool xlnx_hdcp1x_tx_check_rxcapable(struct xlnx_hdcp1x_config *xhdcp1x_tx); +bool xlnx_hdcp1x_read_bksv_from_remote(struct xlnx_hdcp1x_config *xhdcp1x_tx, u32 offset, + void *buf, u32 buf_size); +bool xlnx_hdcp1x_exchangeksvs(struct xlnx_hdcp1x_config *xhdcp1x_tx); +bool xlnx_hdcp1x_computationsstate(struct xlnx_hdcp1x_config *xhdcp1x_tx); +bool xlnx_hdcp1x_tx_validaterxstate(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_check_link_integrity(struct xlnx_hdcp1x_config *xhdcp1x_tx); +void xhdcp1x_tx_set_check_linkstate(struct xlnx_hdcp1x_config *xhdcp1x_tx, int is_enabled); +void xlnx_hdcp1x_tx_process_ri_event(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_is_ksvvalid(u64 ksv); +u64 xlnx_hdcp1x_tx_generate_an(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xhdcp1x_tx_set_keyselect(struct xlnx_hdcp1x_config *xhdcp1x_tx, u8 keyselect); +int xhdcp1x_tx_load_aksv(struct xlnx_hdcp1x_config *xhdcp1x_tx); +void xlnx_hdcp1x_tx_disable(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_tx_reset(struct xlnx_hdcp1x_config *xhdcp1x_tx); +void xlnx_hdcp1x_tx_enable_encryption(struct xlnx_hdcp1x_config *xhdcp1x_tx); +void xlnx_hdcp1x_tx_disable_encryption(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u64 stream_map); +int hdcp1x_tx_protocol_authenticate_sm(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_tx_test_for_repeater(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_tx_read_ksv_list(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_setrepeaterinfo(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_tx_validate_ksv_list(struct xlnx_hdcp1x_config *xhdcp1x_tx, u16 repeaterinfo); +enum hdcp1x_tx_state xlnx_hdcp1x_tx_wait_for_ready(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_get_repeater_info(struct xlnx_hdcp1x_config *xhdcp1x_tx, u16 *info); +int xlnx_hdcp1x_gettopology_maxcascadeexceeded(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_gettopology_maxdevsexceeded(struct xlnx_hdcp1x_config *xhdcp1x_tx); +int xlnx_hdcp1x_set_keys(struct xlnx_hdcp1x_config *xhdcp1x_tx, u8 *data); +int xlnx_hdcp1x_keymngt_init(struct xlnx_hdcp1x_config *xhdcp1x_tx, u8 *data); +void xlnx_hdcp1x_tx_timer_init(struct xlnx_hdcp1x_config *xhdcp1x_tx, + struct xlnx_hdcp_timer_config *tmr_cntrl); +void xlnx_hdcp1x_tx_timer_handler(void *callbackref, u8 tmr_cnt_number); +void xlnx_hdcp1x_tx_start_timer(struct xlnx_hdcp1x_config *xhdcp1x_tx, + u32 timeout, u8 reason_id); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp2x_crypt.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp2x_crypt.c @@ -0,0 +1,494 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx HDCP2X Cryptography driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + * + * This driver provides Xilinx HDCP 2X transmitter cryptographic functionality. + * + * References: + * + * http://www.citi.umich.edu/projects/nfsv4/rfc/pkcs-1v2-1.pdf + * https://www.cryptrec.go.jp/cryptrec_03_spec_cypherlist_files/PDF/pkcs-1v2-12.pdf + * https://www.digital-cp.com/sites/default/files/HDCP%20on%20DisplayPort%20Specification%20Rev2_3.pdf + */ + +#include +#include +#include +#include "xlnx_hdcp2x_tx.h" + +#define BD_MAX_MOD_SIZE (HDCP2X_TX_CERT_RSA_PARAMETER_SIZE / sizeof(u32)) + +#define XHDCP2X_TX_SHA256_SIZE (256 / 8) +#define XHDCP2X_TX_INNER_PADDING_BYTE 0x36 +#define XHDCP2X_TX_OUTER_PADDING_BYTE 0x5C + +/* + * DER encoding T of the Digestinfo value is equal to this hash values + * Reference: http://www.citi.umich.edu/projects/nfsv4/rfc/pkcs-1v2-1.pdf + * Section 8.2.2 and 9.2. + */ +static u8 ti_identifier[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20}; + +/* RSA OAEP masking function */ +static void xlnx_hdcp2x_tx_mg_f1(const u8 *seed, unsigned int seedlen, + u8 *mask, unsigned int mask_len) +{ + u8 hash_data[HDCP2X_TX_CERT_PUB_KEY_N_SIZE] = {0}; + u8 tx_cert_key[HDCP2X_TX_CERT_PUB_KEY_N_SIZE] = {0}; + u8 hash[HDCP2X_TX_SHA256_HASH_SIZE] = {0}; + u32 i; + + memcpy(hash_data, seed, seedlen); + + /* + * Reference: https://www.cryptrec.go.jp/cryptrec_03_spec_cypherlist_files/PDF/pkcs-1v2-12.pdf + * Section: 7.1 + */ + for (i = 0; (i * HDCP2X_TX_SHA256_HASH_SIZE) < mask_len; i++) { + u32 counter; + + counter = ntohl(i); + memcpy(hash_data + seedlen, &counter, HDCP2X_TX_CERT_PUBLIC_EXPONENT_E); + sha256(hash_data, seedlen + HDCP2X_TX_CERT_PUBLIC_EXPONENT_E, hash); + memcpy(tx_cert_key + (i * HDCP2X_TX_SHA256_HASH_SIZE), hash, + HDCP2X_TX_SHA256_HASH_SIZE); + } + memcpy(mask, tx_cert_key, mask_len); +} + +static void xlnx_hdcp2x_tx_memxor(u8 *out, const u8 *inputparam1, + const u8 *inputparam2, u32 size) +{ + u32 i; + + for (i = 0; i < size; i++) + out[i] = inputparam1[i] ^ inputparam2[i]; +} + +/* Reference: PKCS#1 v2.1, Section 7.1.1, Part 2 */ +static void xlnx_hdcp2x_tx_pkcs1_eme_oaep_encode(const u8 *message, const u32 message_length, + const u8 *masking_seed, u8 *encoded_msg) +{ + u8 db_mask[HDCP2X_TX_CERT_PUB_KEY_N_SIZE - HDCP2X_TX_SHA256_HASH_SIZE - 1] = {0}; + u8 db[HDCP2X_TX_CERT_PUB_KEY_N_SIZE - HDCP2X_TX_SHA256_HASH_SIZE - 1] = {0}; + u8 seed_mask[HDCP2X_TX_SHA256_HASH_SIZE] = {0}; + u8 l_hash[HDCP2X_TX_SHA256_HASH_SIZE] = {0}; + u8 seed[HDCP2X_TX_SHA256_HASH_SIZE] = {0}; + + /* Step 2a: l_hash is the empty string */ + sha256(NULL, 0, l_hash); + + /* Step 2b: Generate PS by initializing DB to zeros */ + memcpy(db, l_hash, HDCP2X_TX_SHA256_HASH_SIZE); + + /* Step 2c: Generate DB = lHash || PS || 0x01 || M */ + db[HDCP2X_TX_CERT_PUB_KEY_N_SIZE - message_length - + HDCP2X_TX_SHA256_HASH_SIZE - 2] = 0x01; + + /* + * Step 2d: Generate random seed of length hLen + * The random seed is passed in as an argument to this function. + */ + memcpy(db + HDCP2X_TX_CERT_PUB_KEY_N_SIZE - message_length - + HDCP2X_TX_SHA256_HASH_SIZE - 1, + message, message_length); + + /* Step 2e: Generate dbMask = MGF1(seed, length(DB)) */ + xlnx_hdcp2x_tx_mg_f1(masking_seed, + HDCP2X_TX_SHA256_HASH_SIZE, db_mask, + HDCP2X_TX_CERT_PUB_KEY_N_SIZE - HDCP2X_TX_SHA256_HASH_SIZE + - 1); + + /* Step 2f: Generate maskedDB = DB xor dbMask */ + xlnx_hdcp2x_tx_memxor(db, db, db_mask, + HDCP2X_TX_CERT_PUB_KEY_N_SIZE - HDCP2X_TX_SHA256_HASH_SIZE - 1); + + /* Step 2g: Generate seedMask = MGF(maskedDB, length(seed)) */ + xlnx_hdcp2x_tx_mg_f1(db, + HDCP2X_TX_CERT_PUB_KEY_N_SIZE - HDCP2X_TX_SHA256_HASH_SIZE - 1, + seed_mask, HDCP2X_TX_SHA256_HASH_SIZE); + + /* Step 2h: Generate maskedSeed = seed xor seedMask */ + xlnx_hdcp2x_tx_memxor(seed, masking_seed, seed_mask, + HDCP2X_TX_SHA256_HASH_SIZE); + + /* Step 2i: Form encoded message EM = 0x00 || maskedSeed || maskedDB */ + memset(encoded_msg, 0, HDCP2X_TX_CERT_PUB_KEY_N_SIZE); + memcpy(encoded_msg + 1, seed, HDCP2X_TX_SHA256_HASH_SIZE); + memcpy(encoded_msg + 1 + HDCP2X_TX_SHA256_HASH_SIZE, db, + HDCP2X_TX_CERT_PUB_KEY_N_SIZE - HDCP2X_TX_SHA256_HASH_SIZE - 1); +} + +static int xlnx_hdcp2x_tx_rsa_encrypt(const u8 *rsa_public_key, int public_key_size, + const u8 *exponent_key, int exponent_key_size, + const u8 *msg, int msg_size, u8 *encrypted_msg) +{ + unsigned int *n, *e, *m, *s; + unsigned int mod_size = public_key_size / sizeof(unsigned int); + + if (msg_size != public_key_size) + return -EINVAL; + + n = kzalloc(4 * BD_MAX_MOD_SIZE * sizeof(u32), GFP_KERNEL); + if (!n) + return -ENOMEM; + + /* + * Divide the mem allocated to n into 4 parts such that + * e follows n, m follows e and s follows m. + */ + e = &n[BD_MAX_MOD_SIZE]; + m = &e[BD_MAX_MOD_SIZE]; + s = &m[BD_MAX_MOD_SIZE]; + + mp_conv_from_octets(n, mod_size, rsa_public_key, public_key_size); + mp_conv_from_octets(e, mod_size, exponent_key, exponent_key_size); + + mp_conv_from_octets(m, mod_size, msg, msg_size); + mp_mod_exp(s, m, e, n, mod_size); + mp_conv_to_octets(s, mod_size, encrypted_msg, msg_size); + + kfree(n); + + return 0; +} + +/* Reference: PKCS#1 v2.1, Section 7.1. */ +static int xlnx_hdcp2x_tx_rsa_oae_encrypt(const u8 *rsa_public_key, + int public_key_size, + const u8 *exponent_key, int exponent_key_size, + const u8 *message, const u32 message_length, + const u8 *masking_seed, u8 *encrypted_msg) +{ + int status; + u8 encrypt_msg[HDCP2X_TX_CERT_PUB_KEY_N_SIZE]; + + /* Step 1: Length checking */ + if (message_length > (HDCP2X_TX_CERT_PUB_KEY_N_SIZE - + 2 * HDCP2X_TX_SHA256_HASH_SIZE - 2)) + return -EINVAL; + + /* Step 2: EME-OAEP Encoding */ + xlnx_hdcp2x_tx_pkcs1_eme_oaep_encode(message, message_length, + masking_seed, encrypt_msg); + + /* Step 3: RSA encryption */ + status = xlnx_hdcp2x_tx_rsa_encrypt(rsa_public_key, public_key_size, + exponent_key, exponent_key_size, + encrypt_msg, public_key_size, + encrypted_msg); + if (status) + return -EINVAL; + + return 0; +} + +/* Reference: PKCS#1 v2.1, Section 8.2.2 and Section 9.2 */ +static int xlnx_hdcp2x_tx_rsa_signature_verify(const u8 *msg_ptr, int msg_size, + const u8 *signature, + const u8 *dcp_cert_nvalue, int dcp_cert_nsize, + const u8 *dcp_cert_evalue, int dcp_cert_esize) +{ + u8 encrypted_msg[HDCP2X_TX_CERT_SIGNATURE_SIZE]; + u8 t_hash[HDCP2X_TX_SHA256_HASH_SIZE]; + u8 *encrypted_msg_ptr = NULL; + int i; + int result = 0; + + sha256(msg_ptr, msg_size, t_hash); + + result = xlnx_hdcp2x_tx_rsa_encrypt(dcp_cert_nvalue, dcp_cert_nsize, + dcp_cert_evalue, dcp_cert_esize, + signature, HDCP2X_TX_CERT_SIGNATURE_SIZE, + encrypted_msg); + if (result) + return -EINVAL; + + if (encrypted_msg[0] != 0 || encrypted_msg[1] != 1) + return -EFAULT; + + encrypted_msg_ptr = &encrypted_msg[HDCP2X_TX_CERT_RSVD_SIZE]; + for (i = 0; i < HDCP2X_TX_CERT_PADDING_BYTES; i++) { + if (encrypted_msg_ptr[i] != GENMASK(7, 0)) + return -EFAULT; + } + + encrypted_msg_ptr = &encrypted_msg[HDCP2X_TX_CERT_PADDING_END_DELIMITER]; + if (encrypted_msg_ptr[0]) + return -EFAULT; + + encrypted_msg_ptr = &encrypted_msg[HDCP2X_TX_CERT_PADDING_TI_IDENTIFIER]; + if (memcmp(ti_identifier, encrypted_msg_ptr, HDCP2X_TX_CERT_TI_IDENTIFIER_SIZE)) + return -EFAULT; + + encrypted_msg_ptr = &encrypted_msg[HDCP2X_TX_CERT_PADDING_T_HASH]; + if (memcmp(t_hash, encrypted_msg_ptr, HDCP2X_TX_CERT_T_HASH_SIZE)) + return -EFAULT; + + return result; +} + +int xlnx_hdcp2x_tx_verify_certificate(const struct hdcp2x_tx_cert_rx *rx_certificate, + const u8 *dcp_cert_nvalue, int dcp_cert_nsize, + const u8 *dcp_cert_evalue, int dcp_cert_esize) +{ + return xlnx_hdcp2x_tx_rsa_signature_verify((u8 *)rx_certificate, + (sizeof(struct hdcp2x_tx_cert_rx) - + sizeof(rx_certificate->signature)), + rx_certificate->signature, + dcp_cert_nvalue, dcp_cert_nsize, + dcp_cert_evalue, dcp_cert_esize); +} + +int xlnx_hdcp2x_verify_srm(const u8 *srm, int srm_size, + const u8 *dcp_cert_nvalue, int dcp_cert_nsize, + const u8 *dcp_cert_evalue, int dcp_cert_esize) +{ + return xlnx_hdcp2x_tx_rsa_signature_verify((u8 *)srm, + srm_size - HDCP2X_TX_SRM_SIGNATURE_SIZE, + srm + (srm_size - HDCP2X_TX_SRM_SIGNATURE_SIZE), + dcp_cert_nvalue, dcp_cert_nsize, + dcp_cert_evalue, dcp_cert_esize); +} + +static void xlnx_hdcp2x_tx_aes128_encrypt(const u8 *data, const u8 *key, u8 *output) +{ + struct crypto_aes_ctx ctx; + + aes_expandkey(&ctx, key, HDCP2X_TX_AES128_SIZE); + aes_encrypt(&ctx, output, data); + memzero_explicit(&ctx, sizeof(ctx)); +} + +/* + * This function implements the HMAC Hash message for Authentication. + * Reference: http://www.citi.umich.edu/projects/nfsv4/rfc/pkcs-1v2-1.pdf + */ +static int xlnx_hdcp2x_cmn_hmac_sha256_hash(const u8 *data, int data_size, const u8 *key, + int key_size, u8 *hashed_data) +{ + u8 buffer_in[XHDCP2X_TX_SHA_SIZE] = {0}; + u8 buffer_out[XHDCP2X_TX_SHA_SIZE] = {0}; + u8 ktemp[XHDCP2X_TX_SHA256_SIZE] = {0}; + u8 ktemp2[XHDCP2X_TX_SHA256_SIZE] = {0}; + u8 ipad[XHDCP2X_TX_SHA_KEY_LENGTH + 1] = {0}; + u8 opad[XHDCP2X_TX_SHA_KEY_LENGTH + 1] = {0}; + int i; + + if (data_size + XHDCP2X_TX_SHA_KEY_LENGTH > XHDCP2X_TX_SHA_SIZE) + return -EINVAL; + + if (key_size > XHDCP2X_TX_SHA_KEY_LENGTH) { + sha256(key, key_size, ktemp); + key = ktemp; + key_size = XHDCP2X_TX_SHA256_SIZE; + } + + memcpy(ipad, key, key_size); + memcpy(opad, key, key_size); + + for (i = 0; i < XHDCP2X_TX_SHA_KEY_LENGTH; i++) { + ipad[i] ^= XHDCP2X_TX_INNER_PADDING_BYTE; + opad[i] ^= XHDCP2X_TX_OUTER_PADDING_BYTE; + } + + memcpy(buffer_in, ipad, XHDCP2X_TX_SHA_KEY_LENGTH); + memcpy(buffer_in + XHDCP2X_TX_SHA_KEY_LENGTH, data, data_size); + sha256(buffer_in, XHDCP2X_TX_SHA_KEY_LENGTH + data_size, ktemp2); + + memcpy(buffer_out, opad, XHDCP2X_TX_SHA_KEY_LENGTH); + memcpy(buffer_out + XHDCP2X_TX_SHA_KEY_LENGTH, ktemp2, XHDCP2X_TX_SHA256_SIZE); + sha256(buffer_out, XHDCP2X_TX_SHA_KEY_LENGTH + XHDCP2X_TX_SHA256_SIZE, (u8 *)hashed_data); + + return 0; +} + +void xlnx_hdcp2x_tx_compute_hprime(const u8 *r_rx, const u8 *rxcaps, + const u8 *r_tx, const u8 *txcaps, + const u8 *km, u8 *hprime) +{ + u8 kd[HDCP2X_TX_DKEY_SIZE * HDCP2X_TX_AES128_SIZE] = {0}; + u8 aes_iv[HDCP2X_TX_AES128_SIZE] = {0}; + u8 aes_key[HDCP2X_TX_AES128_SIZE] = {0}; + u8 hash_input[HDCP_2_2_RTX_LEN + HDCP_2_2_RXCAPS_LEN + + HDCP2X_TX_TXCAPS_SIZE] = {0}; + int idx = 0; + + memcpy(aes_key, km, HDCP2X_TX_KM_SIZE); + memcpy(aes_iv, r_tx, HDCP_2_2_RTX_LEN); + memcpy(&aes_iv[HDCP_2_2_RTX_LEN], r_rx, HDCP_2_2_RRX_LEN); + + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, kd); + + /* Determine dkey1, counter is 1: Rrx | 0x01. */ + + /* + * Reference: Section 2.7.1: Key derivation + * https://www.digital-cp.com/sites/default/files/HDCP%20on%20DisplayPort%20Specification%20Rev2_3.pdf + */ + aes_iv[HDCP2X_TX_DKEY] ^= HDCP2X_TX_DKEY_CTR1; + + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, &kd[HDCP2X_TX_KM_SIZE]); + memcpy(hash_input, r_tx, HDCP_2_2_RTX_LEN); + idx += HDCP_2_2_RTX_LEN; + memcpy(&hash_input[idx], rxcaps, HDCP_2_2_RXCAPS_LEN); + idx += HDCP_2_2_RXCAPS_LEN; + memcpy(&hash_input[idx], txcaps, HDCP2X_TX_TXCAPS_SIZE); + + xlnx_hdcp2x_cmn_hmac_sha256_hash(hash_input, sizeof(hash_input), kd, + sizeof(kd), hprime); +} + +void xlnx_hdcp2x_tx_compute_edkey_ks(const u8 *rn, const u8 *km, const u8 *ks, + const u8 *r_rx, const u8 *r_tx, + u8 *encrypted_ks) +{ + u8 aes_iv[HDCP2X_TX_AES128_SIZE] = {0}; + u8 aes_key[HDCP2X_TX_AES128_SIZE] = {0}; + u8 dkey2[HDCP2X_TX_AES128_SIZE] = {0}; + + memcpy(&aes_key[HDCP_2_2_RN_LEN], rn, HDCP_2_2_RN_LEN); + + xlnx_hdcp2x_tx_memxor(aes_key, aes_key, km, HDCP2X_TX_KM_SIZE); + + /* Determine dkey2. */ + /* Add m = Rtx || Rrx. */ + memcpy(aes_iv, r_tx, HDCP_2_2_RTX_LEN); + memcpy(&aes_iv[HDCP_2_2_RTX_LEN], r_rx, HDCP_2_2_RRX_LEN); + + aes_iv[HDCP2X_TX_DKEY] ^= HDCP2X_TX_DKEY_CTR2; + + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, dkey2); + + /* EdkeyKs = Ks XOR (Dkey2 XOR Rrx). */ + /* Rrx XOR Dkey2. */ + memset(encrypted_ks, 0, HDCP_2_2_E_DKEY_KS_LEN); + + memcpy(&encrypted_ks[HDCP_2_2_E_DKEY_KS_LEN - HDCP_2_2_RRX_LEN], r_rx, + HDCP_2_2_RRX_LEN); + + xlnx_hdcp2x_tx_memxor(encrypted_ks, encrypted_ks, dkey2, HDCP2X_TX_AES128_SIZE); + xlnx_hdcp2x_tx_memxor(encrypted_ks, encrypted_ks, ks, HDCP2X_TX_KS_SIZE); +} + +void xlnx_hdcp2x_tx_compute_lprime(const u8 *rn, const u8 *km, + const u8 *r_rx, const u8 *r_tx, + u8 *lprime) +{ + u8 hash_key[HDCP2X_TX_SHA256_HASH_SIZE] = {0}; + u8 aes_iv[HDCP2X_TX_AES128_SIZE] = {0}; + u8 aes_key[HDCP2X_TX_AES128_SIZE] = {0}; + u8 kd[HDCP2X_TX_DKEY_SIZE * HDCP2X_TX_AES128_SIZE] = {0}; + + memcpy(aes_key, km, HDCP2X_TX_KM_SIZE); + memcpy(aes_iv, r_tx, HDCP_2_2_RTX_LEN); + memcpy(&aes_iv[HDCP_2_2_RTX_LEN], r_rx, HDCP_2_2_RRX_LEN); + + /* Compute Dkey0. */ + /* Add m = Rtx || Rrx. */ + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, kd); + + /* Compute Dkey , counter is 1: Rrx | 0x01. */ + aes_iv[HDCP2X_TX_DKEY] ^= HDCP2X_TX_DKEY_CTR1; + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, &kd[HDCP2X_TX_KM_SIZE]); + + /* Create hash with HMAC-SHA256. */ + /* Key: Kd XOR Rrx (least sign. 64 bits). */ + memcpy(&hash_key[HDCP2X_TX_SHA256_HASH_SIZE - HDCP_2_2_RRX_LEN], r_rx, + HDCP_2_2_RRX_LEN); + + xlnx_hdcp2x_tx_memxor(hash_key, hash_key, kd, HDCP2X_TX_SHA256_HASH_SIZE); + xlnx_hdcp2x_cmn_hmac_sha256_hash(rn, HDCP_2_2_RN_LEN, hash_key, + HDCP2X_TX_SHA256_HASH_SIZE, lprime); +} + +void xlnx_hdcp2x_tx_compute_v(const u8 *rn, const u8 *r_rx, const u8 *rx_info, + const u8 *r_tx, const u8 *rcvid_list, const u8 rcvid_count, + const u8 *seq_num_v, const u8 *km, u8 *hash_v) +{ + u8 kd[HDCP2X_TX_DKEY_SIZE * HDCP2X_TX_AES128_SIZE] = {0}; + u8 aes_iv[HDCP2X_TX_AES128_SIZE] = {0}; + u8 aes_key[HDCP2X_TX_AES128_SIZE] = {0}; + u8 hash_input[(HDCP_2_2_MAX_DEVICE_COUNT * HDCP_2_2_RECEIVER_ID_LEN) + + HDCP_2_2_RXINFO_LEN + HDCP_2_2_SEQ_NUM_LEN]; + int idx = 0; + + memcpy(aes_key, km, HDCP2X_TX_KM_SIZE); + + /* Determine Dkey. */ + /* Add m = Rtx || Rrx. */ + memcpy(aes_iv, r_tx, HDCP_2_2_RTX_LEN); + memcpy(&aes_iv[HDCP_2_2_RTX_LEN], r_rx, HDCP_2_2_RRX_LEN); + + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, kd); + + aes_iv[HDCP2X_TX_DKEY] ^= HDCP2X_TX_DKEY_CTR1; + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, &kd[HDCP2X_TX_KM_SIZE]); + + /* Create hash with HMAC-SHA256. */ + /* Input: ReceiverID list || RxInfo || seq_num_V. */ + memcpy(hash_input, rcvid_list, (rcvid_count * HDCP_2_2_RECEIVER_ID_LEN)); + idx += (rcvid_count * HDCP_2_2_RECEIVER_ID_LEN); + memcpy(&hash_input[idx], rx_info, HDCP_2_2_RXINFO_LEN); + idx += HDCP_2_2_RXINFO_LEN; + memcpy(&hash_input[idx], seq_num_v, HDCP_2_2_SEQ_NUM_LEN); + idx += HDCP_2_2_SEQ_NUM_LEN; + + xlnx_hdcp2x_cmn_hmac_sha256_hash(hash_input, idx, kd, sizeof(kd), hash_v); +} + +void xlnx_hdcp2x_tx_compute_m(const u8 *rn, const u8 *r_rx, const u8 *r_tx, + const u8 *stream_id_type, const u8 *k, + const u8 *seq_num_m, const u8 *km, u8 *m_hash) +{ + u8 aes_iv[HDCP2X_TX_AES128_SIZE]; + u8 aes_key[HDCP2X_TX_AES128_SIZE]; + u8 kd[HDCP2X_TX_DKEY_SIZE * HDCP2X_TX_AES128_SIZE]; + u8 sha256_kd[HDCP2X_TX_SHA256_HASH_SIZE]; + u8 hash_input[(HDCP_2_2_MAX_DEVICE_COUNT * HDCP_2_2_RECEIVER_ID_LEN) + + HDCP_2_2_RXINFO_LEN + HDCP_2_2_SEQ_NUM_LEN]; + u16 stream_id_count; + int idx = 0; + + stream_id_count = k[0] << BITS_PER_BYTE; + stream_id_count |= k[1]; + + memcpy(aes_key, km, HDCP2X_TX_KM_SIZE); + memcpy(aes_iv, r_tx, HDCP_2_2_RTX_LEN); + memcpy(&aes_iv[HDCP_2_2_RTX_LEN], r_rx, HDCP_2_2_RRX_LEN); + + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, kd); + + /* Determine Dkey0. */ + /* Add m = Rtx || Rrx. */ + aes_iv[HDCP2X_TX_DKEY] ^= HDCP2X_TX_DKEY_CTR1; + + xlnx_hdcp2x_tx_aes128_encrypt(aes_iv, aes_key, &kd[HDCP2X_TX_KM_SIZE]); + + sha256(kd, sizeof(kd), sha256_kd); + + /* Create hash with HMAC-SHA256. */ + /* Input: StreamID_Type list || seq_num_M. */ + memcpy(hash_input, stream_id_type, (stream_id_count * HDCP2X_TX_STREAMID_TYPE_SIZE)); + idx += (stream_id_count * HDCP2X_TX_STREAMID_TYPE_SIZE); + memcpy(&hash_input[idx], seq_num_m, HDCP_2_2_SEQ_NUM_LEN); + idx += HDCP_2_2_SEQ_NUM_LEN; + + /* HashKey: SHA256(Kd) */ + xlnx_hdcp2x_cmn_hmac_sha256_hash(hash_input, idx, sha256_kd, sizeof(sha256_kd), m_hash); +} + +int xlnx_hdcp2x_tx_encryptedkm(const struct hdcp2x_tx_cert_rx *rx_certificate, + const u8 *km_ptr, u8 *masking_seed, u8 *encrypted_km) +{ + return xlnx_hdcp2x_tx_rsa_oae_encrypt(rx_certificate->N, HDCP2X_TX_CERT_PUB_KEY_N_SIZE, + rx_certificate->e, HDCP2X_TX_CERT_PUB_KEY_E_SIZE, + km_ptr, HDCP2X_TX_KM_SIZE, + masking_seed, encrypted_km); +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp2x_tx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp2x_tx.c @@ -0,0 +1,1267 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx Specific HDCP2X driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + * + * This driver configures Xilinx HDCP IP and its internal modules like Cipher and + * Random Number Generator. + * It consists of: + * - Functionality for checking if the HDCP2X Receiver sink does respond within + * specified times. + * - Message handling from/to the HDCP2X receiver sink. + * + * Reference: + * https://www.digital-cp.com/sites/default/files/HDCP%20on%20DisplayPort%20Specification%20Rev2_3.pdf + */ + +#include +#include +#include +#include +#include +#include "xhdcp2x_tx.h" +#include "xlnx_hdcp2x_tx.h" + +#define XHDCP2X_CIPHER_OFFSET 0U +#define XHDCP2X_RNG_OFFSET 0x1000U + +#define XHDCP2X_SRM_MESSAGE_HEADER_LENGTH 0x05 + +/* Public transmitter DCP LLC key - n=384 bytes, e=1 byte */ + +/* + * Reference: + * https://www.digital-cp.com/sites/default/files/HDCP%20on%20HDMI%20Specification%20Rev2_3.pdf + * Table B.1 + */ +static const u8 hdcp2x_tx_kpubdpc[HDCP2X_TX_KPUB_DCP_LLC_N_SIZE + + XHDCP2X_TX_KPUB_DCP_LLC_E_SIZE] = { + 0xB0, 0xE9, 0xAA, 0x45, 0xF1, 0x29, 0xBA, 0x0A, + 0x1C, 0xBE, 0x17, 0x57, 0x28, 0xEB, 0x2B, 0x4E, + 0x8F, 0xD0, 0xC0, 0x6A, 0xAD, 0x79, 0x98, 0x0F, + 0x8D, 0x43, 0x8D, 0x47, 0x04, 0xB8, 0x2B, 0xF4, + 0x15, 0x21, 0x56, 0x19, 0x01, 0x40, 0x01, 0x3B, + 0xD0, 0x91, 0x90, 0x62, 0x9E, 0x89, 0xC2, 0x27, + 0x8E, 0xCF, 0xB6, 0xDB, 0xCE, 0x3F, 0x72, 0x10, + 0x50, 0x93, 0x8C, 0x23, 0x29, 0x83, 0x7B, 0x80, + 0x64, 0xA7, 0x59, 0xE8, 0x61, 0x67, 0x4C, 0xBC, + 0xD8, 0x58, 0xB8, 0xF1, 0xD4, 0xF8, 0x2C, 0x37, + 0x98, 0x16, 0x26, 0x0E, 0x4E, 0xF9, 0x4E, 0xEE, + 0x24, 0xDE, 0xCC, 0xD1, 0x4B, 0x4B, 0xC5, 0x06, + 0x7A, 0xFB, 0x49, 0x65, 0xE6, 0xC0, 0x00, 0x83, + 0x48, 0x1E, 0x8E, 0x42, 0x2A, 0x53, 0xA0, 0xF5, + 0x37, 0x29, 0x2B, 0x5A, 0xF9, 0x73, 0xC5, 0x9A, + 0xA1, 0xB5, 0xB5, 0x74, 0x7C, 0x06, 0xDC, 0x7B, + 0x7C, 0xDC, 0x6C, 0x6E, 0x82, 0x6B, 0x49, 0x88, + 0xD4, 0x1B, 0x25, 0xE0, 0xEE, 0xD1, 0x79, 0xBD, + 0x39, 0x85, 0xFA, 0x4F, 0x25, 0xEC, 0x70, 0x19, + 0x23, 0xC1, 0xB9, 0xA6, 0xD9, 0x7E, 0x3E, 0xDA, + 0x48, 0xA9, 0x58, 0xE3, 0x18, 0x14, 0x1E, 0x9F, + 0x30, 0x7F, 0x4C, 0xA8, 0xAE, 0x53, 0x22, 0x66, + 0x2B, 0xBE, 0x24, 0xCB, 0x47, 0x66, 0xFC, 0x83, + 0xCF, 0x5C, 0x2D, 0x1E, 0x3A, 0xAB, 0xAB, 0x06, + 0xBE, 0x05, 0xAA, 0x1A, 0x9B, 0x2D, 0xB7, 0xA6, + 0x54, 0xF3, 0x63, 0x2B, 0x97, 0xBF, 0x93, 0xBE, + 0xC1, 0xAF, 0x21, 0x39, 0x49, 0x0C, 0xE9, 0x31, + 0x90, 0xCC, 0xC2, 0xBB, 0x3C, 0x02, 0xC4, 0xE2, + 0xBD, 0xBD, 0x2F, 0x84, 0x63, 0x9B, 0xD2, 0xDD, + 0x78, 0x3E, 0x90, 0xC6, 0xC5, 0xAC, 0x16, 0x77, + 0x2E, 0x69, 0x6C, 0x77, 0xFD, 0xED, 0x8A, 0x4D, + 0x6A, 0x8C, 0xA3, 0xA9, 0x25, 0x6C, 0x21, 0xFD, + 0xB2, 0x94, 0x0C, 0x84, 0xAA, 0x07, 0x29, 0x26, + 0x46, 0xF7, 0x9B, 0x3A, 0x19, 0x87, 0xE0, 0x9F, + 0xEB, 0x30, 0xA8, 0xF5, 0x64, 0xEB, 0x07, 0xF1, + 0xE9, 0xDB, 0xF9, 0xAF, 0x2C, 0x8B, 0x69, 0x7E, + 0x2E, 0x67, 0x39, 0x3F, 0xF3, 0xA6, 0xE5, 0xCD, + 0xDA, 0x24, 0x9B, 0xA2, 0x78, 0x72, 0xF0, 0xA2, + 0x27, 0xC3, 0xE0, 0x25, 0xB4, 0xA1, 0x04, 0x6A, + 0x59, 0x80, 0x27, 0xB5, 0xDA, 0xB4, 0xB4, 0x53, + 0x97, 0x3B, 0x28, 0x99, 0xAC, 0xF4, 0x96, 0x27, + 0x0F, 0x7F, 0x30, 0x0C, 0x4A, 0xAF, 0xCB, 0x9E, + 0xD8, 0x71, 0x28, 0x24, 0x3E, 0xBC, 0x35, 0x15, + 0xBE, 0x13, 0xEB, 0xAF, 0x43, 0x01, 0xBD, 0x61, + 0x24, 0x54, 0x34, 0x9F, 0x73, 0x3E, 0xB5, 0x10, + 0x9F, 0xC9, 0xFC, 0x80, 0xE8, 0x4D, 0xE3, 0x32, + 0x96, 0x8F, 0x88, 0x10, 0x23, 0x25, 0xF3, 0xD3, + 0x3E, 0x6E, 0x6D, 0xBB, 0xDC, 0x29, 0x66, 0xEB, + 0x03 +}; + +/* + * This function is used to load the system renewability messages (SRMs) + * which carries the Receiver ID revocation list. + * Reference: + * https://www.digital-cp.com/sites/default/files/HDCP%20on%20DisplayPort%20Specification%20Rev2_3.pdf + * Section 5.1. + */ +static int xlnx_hdcp2x_loadsrm_revocation_table(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *srm_input) +{ + struct hdcp2x_tx_revoclist *revocation_list = &xhdcp2x_tx->xhdcp2x_revoc_list; + const u8 *kpubdpc = NULL; + const u8 *srmblock = NULL; + const u8 *rcv_id; + u32 block_size, length_field; + u16 num_of_devices; + int ret, i, j; + u8 srm_generator, srm_id; + + srmblock = srm_input; + + /* Byte 1 contains the SRM ID and HDCP2 Indicator field */ + srm_id = srmblock[0]; + + if (srm_id != HDCP2X_TX_SRM_ID) + return -EINVAL; + + /* Byte 5 contains the SRM Generation Number */ + srm_generator = srmblock[4]; + + /* Get the length of the first-generation SRM in bytes.*/ + length_field = drm_hdcp_be24_to_cpu(srmblock + XHDCP2X_SRM_MESSAGE_HEADER_LENGTH); + + /* The size of the first-generation SRM block */ + block_size = length_field + XHDCP2X_SRM_MESSAGE_HEADER_LENGTH; + + kpubdpc = hdcp2x_tx_kpubdpc; + + ret = xlnx_hdcp2x_verify_srm(srmblock, block_size, kpubdpc, HDCP2X_TX_KPUB_DCP_LLC_N_SIZE, + &kpubdpc[HDCP2X_TX_KPUB_DCP_LLC_N_SIZE], + HDCP2X_TX_KPUB_DCP_LLC_E_SIZE); + if (ret) + return -EINVAL; + + srmblock += block_size; + + for (i = 1; i < srm_generator; i++) { + /* + * Byte 1-2 contain the length of the next-generation SRM in bytes. + * Value is in big endian format, Microblaze is little endian. + */ + length_field = srmblock[0] << BITS_PER_BYTE; + length_field |= srmblock[1]; + + block_size = length_field; + + ret = xlnx_hdcp2x_verify_srm(srmblock, block_size, + kpubdpc, HDCP2X_TX_KPUB_DCP_LLC_N_SIZE, + &kpubdpc[HDCP2X_TX_KPUB_DCP_LLC_N_SIZE], + HDCP2X_TX_KPUB_DCP_LLC_E_SIZE); + if (ret) + return -EINVAL; + + srmblock += block_size; + } + + srmblock = srm_input; + + /* Get the length of the first-generation SRM in bytes.*/ + length_field = drm_hdcp_be24_to_cpu(srmblock + XHDCP2X_SRM_MESSAGE_HEADER_LENGTH); + + block_size = length_field + XHDCP2X_SRM_MESSAGE_HEADER_LENGTH; + + /* + * Byte 9,10 contain the number of devices of the firs-generation SRM block + * Value is in big endian format, Microblaze is little endia. + */ + num_of_devices = ((srmblock[8] << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(srmblock[9])); + revocation_list->num_of_devices = 0; + + /* Byte 12 will contain the first byte of the first receiver ID */ + rcv_id = &srmblock[12]; + + for (i = 0; i < num_of_devices; i++) { + if (revocation_list->num_of_devices == + HDCP2X_TX_REVOCATION_LIST_MAX_DEVICES) + return -EINVAL; + memcpy(revocation_list->rcvid[revocation_list->num_of_devices], + rcv_id, XHDCP2X_TX_SRM_RCVID_SIZE); + revocation_list->num_of_devices++; + rcv_id += XHDCP2X_TX_SRM_RCVID_SIZE; + } + srmblock += block_size; + + for (j = 1; j < srm_generator; j++) { + /* + * Byte 1-2 contain the length of the next-generation SRM in bytes. + * Value is in big endian format, Microblaze is little endian. + */ + length_field = srmblock[0] << BITS_PER_BYTE; + length_field |= srmblock[1]; + + block_size = length_field; + + /* + * Byte 3,4 contain the number of devices of the next-generation SRM block + * Value is in big endian format, Microblaze is little endian. + */ + num_of_devices = (srmblock[2] & DRM_HDCP_2_VRL_LENGTH_SIZE) << BITS_PER_BYTE; + num_of_devices |= srmblock[3]; + + /* Byte 5 will contain the first byte of the first receiver ID */ + rcv_id = &srmblock[4]; + + for (i = 0; i < num_of_devices; i++) { + if (revocation_list->num_of_devices == + HDCP2X_TX_REVOCATION_LIST_MAX_DEVICES) + return -EINVAL; + memcpy(revocation_list->rcvid[revocation_list->num_of_devices], + rcv_id, XHDCP2X_TX_SRM_RCVID_SIZE); + revocation_list->num_of_devices++; + rcv_id += XHDCP2X_TX_SRM_RCVID_SIZE; + } + srmblock += block_size; + } + + xhdcp2x_tx->xhdcp2x_info.is_revoc_list_valid = 1; + + return 0; +} + +static bool xlnx_hdcp2x_tx_ds_authenticated(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + return((xhdcp2x_tx->xhdcp2x_info.auth_status == + XHDCP2X_TX_AUTHENTICATED) ? 1 : 0); +} + +const u8 *xlnx_hdcp2x_tx_get_publickey(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + if (!xhdcp2x_tx->xhdcp2x_info.is_enabled) + return NULL; + + return hdcp2x_tx_kpubdpc; +} + +int xlnx_hdcp2x_tx_init(struct xlnx_hdcp2x_config *xhdcp2x_tx, bool is_repeater) +{ + /** + * This array contains the capabilities of the HDCP2X TX core, + * and is transmitted during authentication as part of the AKE_Init message. + */ + u8 hdcp2x_txcaps[] = { 0x02, 0x00, 0x00 }; + + int ret = 0; + + xhdcp2x_tx->txcaps = (u8 *)hdcp2x_txcaps; + xhdcp2x_tx->is_hdmi = xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_HDMI ? 1 : 0; + + xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher.cipher_coreaddress = + xhdcp2x_tx->xhdcp2x_hw.hdcp2xcore_address + XHDCP2X_CIPHER_OFFSET; + xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng.rng_coreaddress = + xhdcp2x_tx->xhdcp2x_hw.hdcp2xcore_address + XHDCP2X_RNG_OFFSET; + + ret = xlnx_hdcp2x_rng_cfg_init(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng); + if (ret < 0) + return -EINVAL; + + xlnx_hdcp2x_rng_enable(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng); + xhdcp2x_tx->xhdcp2x_hw.tx_mode = is_repeater; + + ret = xlnx_hdcp2x_cipher_cfg_init(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher); + if (ret < 0) + return -EINVAL; + + xhdcp2x_tx->xhdcp2x_info.polling_value = 0; + + memcpy(xhdcp2x_tx->xhdcp2x_info.txcaps, (u8 *)xhdcp2x_tx->txcaps, + sizeof(xhdcp2x_tx->xhdcp2x_info.txcaps)); + + xlnx_hdcp2x_cipher_init(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher); + + return ret; +} + +int xlnx_hdcp2x_loadkeys(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 *srm_key, u8 *lc128_key) +{ + int ret; + + xhdcp2x_tx->srmkey = (u8 *)srm_key; + xhdcp2x_tx->lc128key = (u8 *)lc128_key; + + xlnx_hdcp2x_cipher_set_keys(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher, + xhdcp2x_tx->lc128key, XHDCP2X_CIPHER_REG_LC128_1_OFFSET, + XHDCP2X_TX_LC128_SIZE); + + ret = xlnx_hdcp2x_loadsrm_revocation_table(xhdcp2x_tx, xhdcp2x_tx->srmkey); + if (ret < 0) + return -EINVAL; + + return ret; +} + +u8 xlnx_hdcp2x_tx_is_device_revoked(struct xlnx_hdcp2x_config *xhdcp2x_tx, + u8 *rcvid) +{ + struct hdcp2x_tx_revoclist *revoc_list = NULL; + u32 result, i; + + revoc_list = &xhdcp2x_tx->xhdcp2x_revoc_list; + + for (i = 0; i < revoc_list->num_of_devices; i++) { + result = memcmp(rcvid, revoc_list->rcvid[i], XHDCP2X_TX_SRM_RCVID_SIZE); + if (!result) + return 1; + } + + return 0; +} + +static void xlnx_hdcp2x_tx_enble(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + xhdcp2x_tx->xhdcp2x_info.is_enabled = 1; + xlnx_hdcp2x_cipher_enable(xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher.cipher_coreaddress); + xlnx_hdcp2x_cipher_set_lanecount(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher, + xhdcp2x_tx->lane_count); + xlnx_hdcp_tmrcntr_stop(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0); +} + +static u8 xlnx_hdcp2x_tx_is_ds_repeater(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + return (xhdcp2x_tx->xhdcp2x_hw.tx_mode != XHDCP2X_TX_TRANSMITTER) ? 1 : 0; +} + +static int xlnx_hdcp2x_tx_start_authenticate(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + if (!xhdcp2x_tx->xhdcp2x_info.is_enabled) + return -EINVAL; + + xhdcp2x_tx->xhdcp2x_info.is_rcvr_hdcp2x_capable = 0; + + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_AUTHENTICATION_BUSY; + + xhdcp2x_tx->xhdcp2x_info.curr_state = H0_HDCP2X_TX_NO_RX_ATTACHED; + xhdcp2x_tx->xhdcp2x_info.prev_state = H0_HDCP2X_TX_NO_RX_ATTACHED; + + if (xlnx_hdcp2x_tx_is_ds_repeater(xhdcp2x_tx)) + xhdcp2x_tx->xhdcp2x_info.is_content_stream_type_set = 0; + + return 0; +} + +void xlnx_start_hdcp2x_engine(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + xlnx_hdcp2x_tx_enble(xhdcp2x_tx); + xlnx_hdcp2x_tx_start_authenticate(xhdcp2x_tx); +} + +static void xlnx_hdcp2x_tx_disable(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + xhdcp2x_tx->xhdcp2x_info.is_enabled = 0; + xlnx_hdcp2x_cipher_disable(xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher.cipher_coreaddress); +} + +int xlnx_hdcp2x_tx_reset(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + if (!xhdcp2x_tx->xhdcp2x_info.is_enabled) { + dev_dbg(xhdcp2x_tx->dev, "HDCP is not started"); + return -EINVAL; + } + xhdcp2x_tx->xhdcp2x_info.auth_status = XHDCP2X_TX_UNAUTHENTICATED; + + xhdcp2x_tx->xhdcp2x_info.curr_state = H0_HDCP2X_TX_NO_RX_ATTACHED; + xhdcp2x_tx->xhdcp2x_info.prev_state = H0_HDCP2X_TX_NO_RX_ATTACHED; + xhdcp2x_tx->xhdcp2x_info.lc_counter = 0; + + xlnx_hdcp_tmrcntr_stop(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0); + xlnx_hdcp_tmrcntr_reset(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, 0); + + xhdcp2x_tx->xhdcp2x_info.content_stream_type = XHDCP2X_STREAMTYPE_0; + xhdcp2x_tx->xhdcp2x_info.is_content_stream_type_set = 1; + xhdcp2x_tx->xhdcp2x_revoc_list.num_of_devices = 0; + xlnx_hdcp2x_tx_disable_encryption(xhdcp2x_tx); + + xlnx_hdcp2x_tx_disable(xhdcp2x_tx); + + return 0; +} + +void xlnx_hdcp2x_tx_enable_encryption(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + if (xlnx_hdcp2x_tx_ds_authenticated(xhdcp2x_tx)) { + xlnx_hdcp2x_tx_cipher_update_encryption(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher, + 1); + dev_dbg(xhdcp2x_tx->dev, "enable encryption"); + } +} + +void xlnx_hdcp2x_tx_disable_encryption(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + xlnx_hdcp2x_tx_cipher_update_encryption(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher, 0); + dev_dbg(xhdcp2x_tx->dev, "disable encryption"); +} + +bool xlnx_hdcp2x_downstream_capbility(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + u8 rxcaps[HDCP_2_2_RXCAPS_LEN] = {0}; + u8 hdcp2_version; + + if (xhdcp2x_tx->is_hdmi) { + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_VER_OFFSET, + (void *)&hdcp2_version, + sizeof(hdcp2_version)); + + return (hdcp2_version & HDCP_2_2_HDMI_SUPPORT_MASK); + } + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_RX_CAPS_OFFSET, + (void *)rxcaps, + HDCP_2_2_RXCAPS_LEN); + + return ((rxcaps[0] == HDCP_2_2_RX_CAPS_VERSION_VAL) && + HDCP_2_2_DP_HDCP_CAPABLE(rxcaps[2])); +} + +static u32 xlnx_hdcp2x_tx_get_timer_count(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + return xlnx_hdcp_tmrcntr_get_value(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0); +} + +static int xlnx_hdcp2x_hdmitx_read_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 msg_id) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + int msg_read = 0; + int status = -EINVAL; + + tx_msg->msg = msg_id; + + switch (msg_id) { + case HDCP_2_2_AKE_SEND_CERT: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RD_MSG_OFFSET, + (u8 *)&tx_msg->msg_type.msg_id, + sizeof(struct hdcp2x_tx_ake_sendcert)); + + if (msg_read == sizeof(struct hdcp2x_tx_ake_sendcert)) + status = 0; + break; + case HDCP_2_2_AKE_SEND_HPRIME: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RD_MSG_OFFSET, + (u8 *)&tx_msg->msg_type.msg_id, + sizeof(struct hdcp2x_tx_ake_sendprime)); + + if (msg_read == sizeof(struct hdcp2x_tx_ake_sendprime)) + status = 0; + break; + case HDCP_2_2_AKE_SEND_PAIRING_INFO: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RD_MSG_OFFSET, + (u8 *)&tx_msg->msg_type.msg_id, + sizeof(struct + hdcp2x_tx_ake_send_pairing_info)); + + if (msg_read == sizeof(struct hdcp2x_tx_ake_send_pairing_info)) + status = 0; + break; + case HDCP_2_2_LC_SEND_LPRIME: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RD_MSG_OFFSET, + (u8 *)&tx_msg->msg_type.msg_id, + sizeof(struct hdcp2x_tx_lc_send_lc_prime)); + + if (msg_read == sizeof(struct hdcp2x_tx_lc_send_lc_prime)) + status = 0; + break; + case HDCP_2_2_REP_SEND_RECVID_LIST: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RD_MSG_OFFSET, + (u8 *)&tx_msg->msg_type.msg_id, + sizeof(struct hdcp2x_tx_rpt_auth_send_rcvid_list)); + + if (msg_read == sizeof(struct hdcp2x_tx_rpt_auth_send_rcvid_list)) + status = 0; + break; + case HDCP_2_2_REP_STREAM_READY: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RD_MSG_OFFSET, + (u8 *)&tx_msg->msg_type.msg_id, + sizeof(struct + hdcp2x_tx_rpt_auth_stream_ready)); + + if (msg_read == sizeof(struct hdcp2x_tx_rpt_auth_stream_ready)) + status = 0; + break; + default: + status = -EINVAL; + break; + } + + return status; +} + +int xlnx_hdcp2x_tx_read_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 msg_id) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + int msg_read = 0; + int status = -EINVAL; + + if (xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_HDMI) + return xlnx_hdcp2x_hdmitx_read_msg(xhdcp2x_tx, msg_id); + + switch (msg_id) { + case HDCP_2_2_AKE_SEND_CERT: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_CERT_RX_OFFSET, + tx_msg->msg_type.ake_send_cert.cert_rx.rcvid, + HDCP2X_TX_CERT_SIZE); + msg_read += + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_R_RX_OFFSET, + tx_msg->msg_type.ake_send_cert.r_rx, + HDCP_2_2_RRX_LEN); + msg_read += + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_RX_CAPS_OFFSET, + tx_msg->msg_type.ake_send_cert.rxcaps, + HDCP_2_2_RXCAPS_LEN); + if (msg_read == (HDCP2X_TX_CERT_SIZE + + HDCP_2_2_RRX_LEN + + HDCP_2_2_RXCAPS_LEN)) + status = 0; + break; + case HDCP_2_2_AKE_SEND_HPRIME: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_H_PRIME_OFFSET, + tx_msg->msg_type.ake_send_prime.h_prime, + HDCP_2_2_H_PRIME_LEN); + if (msg_read == HDCP_2_2_H_PRIME_LEN) + status = 0; + break; + case HDCP_2_2_AKE_SEND_PAIRING_INFO: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_E_KH_KM_PAIRING_OFFSET, + tx_msg->msg_type.ake_send_pairing_info.ekh_km, + HDCP_2_2_E_KH_KM_LEN); + if (msg_read == HDCP_2_2_E_KH_KM_LEN) + status = 0; + break; + case HDCP_2_2_LC_SEND_LPRIME: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_L_PRIME_OFFSET, + tx_msg->msg_type.lcsend_lcprime.lprime, + HDCP_2_2_L_PRIME_LEN); + if (msg_read == HDCP_2_2_L_PRIME_LEN) + status = 0; + break; + case HDCP_2_2_REP_SEND_RECVID_LIST: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_RX_INFO_OFFSET, + tx_msg->msg_type.rpt_auth_send_rcvid.rxinfo, + HDCP_2_2_RXINFO_LEN); + msg_read += + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_SEQ_NUM_V_OFFSET, + tx_msg->msg_type.rpt_auth_send_rcvid.seq_num_v, + HDCP_2_2_SEQ_NUM_LEN); + msg_read += + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_V_PRIME_OFFSET, + tx_msg->msg_type.rpt_auth_send_rcvid.vprime, + HDCP_2_2_V_PRIME_HALF_LEN); + msg_read += + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_RCVR_ID_LST_OFFSET, (u8 *) + tx_msg->msg_type.rpt_auth_send_rcvid.rcvids, + HDCP2X_TX_HDCPPORT_RCVR_ID_LST_MAX_SIZE); + if (msg_read == HDCP_2_2_RXINFO_LEN + + HDCP_2_2_SEQ_NUM_LEN + + HDCP_2_2_V_PRIME_HALF_LEN + + HDCP2X_TX_HDCPPORT_RCVR_ID_LST_MAX_SIZE) + status = 0; + break; + case HDCP_2_2_REP_STREAM_READY: + msg_read = + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_M_PRIME_OFFSET, + tx_msg->msg_type.rpt_auth_stream_rdy.m_prime, + HDCP_2_2_MPRIME_LEN); + if (msg_read == HDCP_2_2_MPRIME_LEN) + status = 0; + break; + default: + status = -EINVAL; + break; + } + + return status; +} + +static int xlnx_hdmi_hdcp2x_tx_write_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg tx_msg; + int message_size = 0; + int status = -EINVAL; + + memcpy(&tx_msg, xhdcp2x_tx->msg_buffer, sizeof(struct xhdcp2x_tx_msg)); + + switch (tx_msg.msg_type.msg_id) { + case HDCP_2_2_AKE_INIT: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_ake_init) + 1); + if (message_size == sizeof(struct hdcp2x_tx_ake_init) + 1) + status = 0; + break; + case HDCP_2_2_AKE_NO_STORED_KM: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_ake_no_stored_km) + + 1); + + if (message_size == sizeof(struct hdcp2x_tx_ake_no_stored_km) + 1) + status = 0; + break; + case HDCP_2_2_AKE_STORED_KM: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_ake_stored_km) + + 1); + + if (message_size == (sizeof(struct hdcp2x_tx_ake_stored_km) + 1)) + status = 0; + break; + case HDCP_2_2_LC_INIT: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_lc_init) + 1); + + if (message_size == (sizeof(struct hdcp2x_tx_lc_init) + 1)) + status = 0; + break; + case HDCP_2_2_SKE_SEND_EKS: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_ske_send_eks) + + 1); + + if (message_size == (sizeof(struct hdcp2x_tx_ske_send_eks) + 1)) + status = 0; + break; + case HDCP2X_TX_TYPE_VALUE: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_TYPE_VALUE_OFFSET, + (u8 *)&xhdcp2x_tx + ->xhdcp2x_info.content_stream_type, + HDCP2X_TX_HDCPPORT_TYPE_VALUE_SIZE); + if (message_size == HDCP2X_TX_HDCPPORT_TYPE_VALUE_SIZE) + status = 0; + break; + case HDCP_2_2_REP_SEND_ACK: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_rpt_auth_send_ack) + + 1); + + if (message_size == (sizeof(struct hdcp2x_tx_rpt_auth_send_ack) + 1)) + status = 0; + break; + case HDCP_2_2_REP_STREAM_MANAGE: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET, + (u8 *)&tx_msg, + sizeof(struct hdcp2x_tx_rpt_auth_stream_manage) + + 1); + + if (message_size == (sizeof(struct hdcp2x_tx_rpt_auth_stream_manage) + 1)) + status = 0; + break; + default: + status = -EINVAL; + break; + } + return status; +} + +static int xlnx_hdcp2x_tx_write_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg buffer; + int message_size = 0; + int status = -EINVAL; + + memcpy(&buffer, xhdcp2x_tx->msg_buffer, sizeof(struct xhdcp2x_tx_msg)); + + if (xhdcp2x_tx->is_hdmi) + return xlnx_hdmi_hdcp2x_tx_write_msg(xhdcp2x_tx); + + switch (buffer.msg_type.msg_id) { + case HDCP_2_2_AKE_INIT: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_R_TX_OFFSET, + buffer.msg_type.ake_int.r_tx, + HDCP_2_2_RTX_LEN); + message_size += + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_TX_CAPS_OFFSET, + buffer.msg_type.ake_int.txcaps, + HDCP2X_TX_TXCAPS_SIZE); + + if (message_size == (HDCP_2_2_RTX_LEN + HDCP2X_TX_TXCAPS_SIZE)) + status = 0; + break; + case HDCP_2_2_AKE_NO_STORED_KM: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_E_KPUB_KM_OFFSET, + buffer.msg_type.ake_nostored_km.ek_pubkm, + HDCP2X_TX_HDCPPORT_E_KPUB_KM_SIZE); + + if (message_size == HDCP2X_TX_HDCPPORT_E_KPUB_KM_SIZE) + status = 0; + break; + case HDCP_2_2_AKE_STORED_KM: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_E_KH_KM_OFFSET, + buffer.msg_type.ake_stored_km.ekh_km, + HDCP_2_2_E_KH_KM_LEN); + message_size += + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_M_OFFSET, + buffer.msg_type.ake_stored_km.r_tx, + HDCP_2_2_E_KH_KM_LEN); + + if (message_size == (HDCP_2_2_E_KH_KM_LEN + HDCP_2_2_E_KH_KM_LEN)) + status = 0; + break; + case HDCP_2_2_LC_INIT: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_R_N_OFFSET, + buffer.msg_type.lcinit.rn, + HDCP_2_2_RN_LEN); + if (message_size == HDCP_2_2_RN_LEN) + status = 0; + break; + case HDCP_2_2_SKE_SEND_EKS: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_E_DKEY_KS_OFFSET, + buffer.msg_type.ske_send_eks.edkeys_ks, + HDCP_2_2_E_DKEY_KS_LEN); + message_size += + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_R_IV_OFFSET, + buffer.msg_type.ske_send_eks.riv, + HDCP_2_2_RIV_LEN); + + if (message_size == (HDCP_2_2_E_DKEY_KS_LEN + + HDCP_2_2_RIV_LEN)) + status = 0; + break; + case HDCP2X_TX_TYPE_VALUE: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_TYPE_VALUE_OFFSET, + (u8 *)&xhdcp2x_tx + ->xhdcp2x_info.content_stream_type, + HDCP2X_TX_HDCPPORT_TYPE_VALUE_SIZE); + if (message_size == HDCP2X_TX_HDCPPORT_TYPE_VALUE_SIZE) + status = 0; + break; + case HDCP_2_2_REP_SEND_ACK: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_V_OFFSET, + buffer.msg_type.rpt_auth_send_ack.V, + HDCP_2_2_V_PRIME_HALF_LEN); + if (message_size == HDCP_2_2_V_PRIME_HALF_LEN) + status = 0; + break; + case HDCP_2_2_REP_STREAM_MANAGE: + message_size = + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_SEQ_NUM_M_OFFSET, + buffer.msg_type.rpt_auth_stream_mng.seq_num_m, + HDCP_2_2_SEQ_NUM_LEN); + message_size += + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_K_OFFSET, + buffer.msg_type.rpt_auth_stream_mng.K, + HDCP2X_TX_HDCPPORT_K_SIZE); + message_size += + xhdcp2x_tx->handlers.wr_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_STREAM_ID_TYPE_OFFSET, + buffer.msg_type.rpt_auth_stream_mng.streamid_type, + HDCP2X_TX_HDCPPORT_STREAM_ID_TYPE_SIZE); + if (message_size == (HDCP_2_2_SEQ_NUM_LEN + + HDCP2X_TX_HDCPPORT_K_SIZE + + HDCP2X_TX_HDCPPORT_STREAM_ID_TYPE_SIZE)) + status = 0; + break; + default: + status = -EINVAL; + break; + } + + return status; +} + +void xlnx_hdcp2x_tx_process_cp_irq(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + u8 rx_status = 0; + + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP2X_TX_HDCPPORT_RX_STATUS_OFFSET, + &rx_status, + HDCP_2_2_HDMI_RXSTATUS_LEN); + xhdcp2x_tx->xhdcp2x_info.dp_rx_status = rx_status; +} + +int xlnx_hdcp2x_task_monitor(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + enum hdcp2x_tx_state new_state; + + if (!xhdcp2x_tx->xhdcp2x_info.is_enabled) + return (int)(xhdcp2x_tx->xhdcp2x_info.auth_status); + + new_state = hdcp2x_tx_protocol_authenticate_sm(xhdcp2x_tx); + + xhdcp2x_tx->xhdcp2x_info.prev_state = + xhdcp2x_tx->xhdcp2x_info.curr_state; + xhdcp2x_tx->xhdcp2x_info.curr_state = new_state; + + return xhdcp2x_tx->xhdcp2x_info.auth_status; +} + +void xlnx_hdcp2x_tx_timer_init(struct xlnx_hdcp2x_config *xhdcp2x_tx, + struct xlnx_hdcp_timer_config *tmr_cntrl) +{ + xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr = *tmr_cntrl; + + xlnx_hdcp_tmrcntr_set_options(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0, + XTC_INT_MODE_OPTION | XTC_DOWN_COUNT_OPTION); + + xlnx_hdcp_tmrcntr_set_options(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_1, XTC_AUTO_RELOAD_OPTION); +} + +void xlnx_hdcp2x_tx_start_timer(struct xlnx_hdcp2x_config *xhdcp2x_tx, + u32 timeout, u8 reason_id) +{ + u32 ticks = (u32)(xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr.hw_config.sys_clock_freq + / XHDCP2X_TX_CLKDIV_MHZ) * timeout * XHDCP2X_TX_CLKDIV_HZ; + + xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired = 0; + xhdcp2x_tx->xhdcp2x_internal_timer.reason_id = reason_id; + xhdcp2x_tx->xhdcp2x_internal_timer.initial_ticks = ticks; + + if (reason_id != XHDCP2X_TX_TS_UNDEFINED && + reason_id != XHDCP2X_TX_TS_RX_REAUTH_CHECK && + reason_id != XHDCP2X_TX_TS_RX_REAUTH_CHECK) + xhdcp2x_tx->xhdcp2x_info.msg_available = 0; + + xlnx_hdcp_tmrcntr_set_reset_value(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0, ticks); + + xlnx_hdcp_tmrcntr_start(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0); +} + +void xlnx_hdcp2x_tx_timer_handler(void *callbackref, u8 tmr_cnt_number) +{ + struct xlnx_hdcp2x_config *xhdcp2x_tx = (struct xlnx_hdcp2x_config *)callbackref; + + if (tmr_cnt_number == XHDCP2X_TX_TIMER_CNTR_1) + return; + + xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired = 1; + if (xhdcp2x_tx->xhdcp2x_info.is_enabled) + xlnx_hdcp2x_tx_read_rxstatus(xhdcp2x_tx); +} + +void xlnx_hdcp2x_tx_read_rxstatus(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + u8 read_buffer[2]; + + if (xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_HDMI) { + xhdcp2x_tx->handlers.rd_handler(xhdcp2x_tx->interface_ref, + HDCP_2_2_HDMI_REG_RXSTATUS_OFFSET, + (void *)read_buffer, + sizeof(read_buffer)); + + xhdcp2x_tx->xhdcp2x_info.rx_status = read_buffer[0] + | (read_buffer[1] << BITS_PER_BYTE); + } +} + +int xlnx_hdcp2x_tx_write_type_value(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg_type.msg_id = HDCP2X_TX_TYPE_VALUE; + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +int xlnx_hdcp2x_tx_write_ake_init(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_AKE_INIT; + + xlnx_hdcp2x_rng_get_random_number(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng, + xhdcp2x_tx->xhdcp2x_info.r_tx, + HDCP_2_2_RTX_LEN, HDCP_2_2_RTX_LEN); + + memcpy(&tx_msg->msg_type.ake_int.r_tx, xhdcp2x_tx->xhdcp2x_info.r_tx, + sizeof(tx_msg->msg_type.ake_int.r_tx)); + memcpy(&tx_msg->msg_type.ake_int.txcaps, xhdcp2x_tx->xhdcp2x_info.txcaps, + sizeof(tx_msg->msg_type.ake_int.txcaps)); + + dev_dbg(xhdcp2x_tx->dev, "write ake init"); + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +int xlnx_hdcp2x_tx_write_ske_send_eks(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *edkey_ptr, const u8 *riv_ptr) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_SKE_SEND_EKS; + + memcpy(tx_msg->msg_type.ske_send_eks.edkeys_ks, edkey_ptr, + sizeof(tx_msg->msg_type.ske_send_eks.edkeys_ks)); + + memcpy(tx_msg->msg_type.ske_send_eks.riv, riv_ptr, + sizeof(tx_msg->msg_type.ske_send_eks.riv)); + + dev_dbg(xhdcp2x_tx->dev, "write ske send eks"); + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +int xlnx_hdcp2x_tx_write_lcinit(struct xlnx_hdcp2x_config *xhdcp2x_tx, const u8 *rn_ptr) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_LC_INIT; + + memcpy(tx_msg->msg_type.lcinit.rn, rn_ptr, sizeof(tx_msg->msg_type.lcinit.rn)); + + dev_dbg(xhdcp2x_tx->dev, "write lc-init\r"); + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +int xlnx_hdcp2x_tx_write_ake_storedkm(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_AKE_STORED_KM; + + memcpy(tx_msg->msg_type.ake_stored_km.ekh_km, hdcp2x_tx_pairing_info->ekh_km, + sizeof(tx_msg->msg_type.ake_stored_km.ekh_km)); + memcpy(tx_msg->msg_type.ake_stored_km.r_tx, hdcp2x_tx_pairing_info->rtx, + sizeof(tx_msg->msg_type.ake_stored_km.r_tx)); + memcpy(tx_msg->msg_type.ake_stored_km.r_rx, hdcp2x_tx_pairing_info->rrx, + sizeof(tx_msg->msg_type.ake_stored_km.r_rx)); + + dev_dbg(xhdcp2x_tx->dev, "write AKE stored km"); + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +int xlnx_hdcp2x_tx_write_akenostored_km(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const struct hdcp2x_tx_pairing_info *pairing_info, + const struct hdcp2x_tx_cert_rx *cert_ptr) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + u8 masking_seed[HDCP2X_TX_KM_MSK_SEED_SIZE]; + u8 ek_pubkm[HDCP_2_2_E_KPUB_KM_LEN]; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_AKE_NO_STORED_KM; + + xlnx_hdcp2x_rng_get_random_number(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng, + masking_seed, HDCP2X_TX_KM_MSK_SEED_SIZE, + HDCP2X_TX_KM_MSK_SEED_SIZE); + xlnx_hdcp2x_tx_encryptedkm((const struct hdcp2x_tx_cert_rx *)cert_ptr, + pairing_info->km, masking_seed, ek_pubkm); + + memcpy(tx_msg->msg_type.ake_nostored_km.ek_pubkm, ek_pubkm, + sizeof(tx_msg->msg_type.ake_nostored_km.ek_pubkm)); + + dev_dbg(xhdcp2x_tx->dev, "write AKE no stored km"); + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +int xlnx_hdcp2x_tx_write_rptr_auth_send_ack(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *v_ptr) +{ + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_REP_SEND_ACK; + + memcpy(tx_msg->msg_type.rpt_auth_send_ack.V, v_ptr, + sizeof(tx_msg->msg_type.rpt_auth_send_ack.V)); + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +struct hdcp2x_tx_pairing_info *xlnx_hdcp2x_tx_get_pairing_info(struct xlnx_hdcp2x_config + *xhdcp2x_tx, const u8 *rcvid) +{ + struct hdcp2x_tx_pairing_info *pairing_info_ptr; + u8 illegal_rcvd[] = {0x0, 0x0, 0x0, 0x0, 0x0}; + int i = 0; + + if (!memcmp(rcvid, illegal_rcvd, HDCP_2_2_RECEIVER_ID_LEN)) + return NULL; + + for (i = 0; i < XHDCP2X_TX_MAX_STORED_PAIRINGINFO; i++) { + pairing_info_ptr = &xhdcp2x_tx->xhdcp2x_info.pairing_info[i]; + if (!memcmp(rcvid, pairing_info_ptr->rcvid, HDCP_2_2_RECEIVER_ID_LEN)) + return pairing_info_ptr; + } + + return NULL; +} + +void xlnx_hdcp2x_tx_invalidate_paring_info(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *rcvid) +{ + struct hdcp2x_tx_pairing_info *pairing_info_ptr = + xlnx_hdcp2x_tx_get_pairing_info(xhdcp2x_tx, rcvid); + + if (!pairing_info_ptr) + return; + + memset(pairing_info_ptr, 0, sizeof(struct hdcp2x_tx_pairing_info)); +} + +struct hdcp2x_tx_pairing_info *xlnx_hdcp2x_tx_update_pairinginfo(struct xlnx_hdcp2x_config + *xhdcp2x_tx, + struct hdcp2x_tx_pairing_info *pairing_info, + u8 ready) +{ + struct hdcp2x_tx_pairing_info *xhdcp2x_pairing_info_ptr; + int i; + int i_match = 0; + u8 match = 0; + + for (i = 0; i < XHDCP2X_TX_MAX_STORED_PAIRINGINFO; i++) { + xhdcp2x_pairing_info_ptr = + &xhdcp2x_tx->xhdcp2x_info.pairing_info[i]; + if (!(xhdcp2x_pairing_info_ptr->ready) && !(match)) { + i_match = i; + match = 1; + } + if (!memcmp(pairing_info->rcvid, xhdcp2x_pairing_info_ptr->rcvid, + HDCP_2_2_RECEIVER_ID_LEN)) { + i_match = i; + break; + } + } + xhdcp2x_pairing_info_ptr = &xhdcp2x_tx->xhdcp2x_info.pairing_info[i_match]; + + memcpy(xhdcp2x_pairing_info_ptr, pairing_info, sizeof(struct hdcp2x_tx_pairing_info)); + xhdcp2x_pairing_info_ptr->ready = ready; + + return xhdcp2x_pairing_info_ptr; +} + +int xlnx_hdcp2x_tx_rptr_auth_stream_mng(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + struct hdcp2x_tx_pairing_info *xhdcp2x_pairing_info = + (struct hdcp2x_tx_pairing_info *) + xhdcp2x_tx->xhdcp2x_info.state_context; + struct xhdcp2x_tx_msg *tx_msg = (struct xhdcp2x_tx_msg *)xhdcp2x_tx->msg_buffer; + + tx_msg->msg = (xhdcp2x_tx->xhdcp2x_hw.protocol != XHDCP2X_TX_DP) ? + HDCP_2_2_HDMI_REG_WR_MSG_OFFSET : + HDCP2X_TX_HDCPPORT_WRITE_MSG_OFFSET; + tx_msg->msg_type.msg_id = HDCP_2_2_REP_STREAM_MANAGE; + + drm_hdcp_cpu_to_be24(tx_msg->msg_type.rpt_auth_stream_mng.seq_num_m, + xhdcp2x_tx->xhdcp2x_info.seq_num_m); + + /* The parameter K is always set to 0x1 by the HDCP transmitter */ + /* Value is sent in big endian format */ + tx_msg->msg_type.rpt_auth_stream_mng.K[0] = 0x0; + tx_msg->msg_type.rpt_auth_stream_mng.K[1] = 0x1; + + tx_msg->msg_type.rpt_auth_stream_mng.streamid_type[0] = HDCP_STREAM_TYPE0; + tx_msg->msg_type.rpt_auth_stream_mng.streamid_type[1] = + (u8)xhdcp2x_tx->xhdcp2x_info.content_stream_type; + + xlnx_hdcp2x_tx_compute_m(xhdcp2x_tx->xhdcp2x_info.rn, + xhdcp2x_tx->xhdcp2x_info.r_rx, + xhdcp2x_tx->xhdcp2x_info.r_tx, + tx_msg->msg_type.rpt_auth_stream_mng.streamid_type, + tx_msg->msg_type.rpt_auth_stream_mng.K, + tx_msg->msg_type.rpt_auth_stream_mng.seq_num_m, + xhdcp2x_pairing_info->km, + xhdcp2x_tx->xhdcp2x_info.M); + + /* Increment the M on every Stream message */ + xhdcp2x_tx->xhdcp2x_info.seq_num_m++; + + return xlnx_hdcp2x_tx_write_msg(xhdcp2x_tx); +} + +void xlnx_hdcp2x_tx_generatekm(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 *kmptr) +{ + xlnx_hdcp2x_rng_get_random_number(&xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_rng, + kmptr, HDCP2X_TX_KM_SIZE, + HDCP2X_TX_KM_SIZE); +} + +int xlnx_hdcp2x_tx_wait_for_receiver(struct xlnx_hdcp2x_config *xhdcp2x_tx, + int expected_size, u8 ready_bit) +{ + u32 timer_cnt = 0; + u32 interval_cnt = xhdcp2x_tx->xhdcp2x_info.polling_value * + ((u32)(xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr.hw_config.sys_clock_freq) + / XHDCP2X_TX_CLKDIV_HZ); + + if (xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired) { + if (xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_DP) { + xhdcp2x_tx->xhdcp2x_info.msg_available = 1; + return 0; + } + if ((!ready_bit && ((xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_AVAIL_BYTES_MASK) == expected_size)) || + (ready_bit && (xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_READY_MASK))) { + xhdcp2x_tx->xhdcp2x_info.msg_available = 1; + return 0; + } + + return -EINVAL; + } + timer_cnt = xlnx_hdcp2x_tx_get_timer_count(xhdcp2x_tx); + + if (!xhdcp2x_tx->xhdcp2x_info.polling_value || + ((xhdcp2x_tx->xhdcp2x_internal_timer.initial_ticks - timer_cnt) + >= interval_cnt)) { + xhdcp2x_tx->xhdcp2x_internal_timer.initial_ticks = timer_cnt; + if (xhdcp2x_tx->xhdcp2x_hw.protocol == XHDCP2X_TX_DP) { + if (xhdcp2x_tx->xhdcp2x_internal_timer.reason_id == + HDCP_2_2_AKE_SEND_HPRIME) { + if (xhdcp2x_tx->xhdcp2x_info.dp_rx_status & + XHDCP2X_RX_STATUS_H_PRIME_AVAILABLE) { + xhdcp2x_tx->xhdcp2x_info.dp_rx_status &= + ~XHDCP2X_RX_STATUS_H_PRIME_AVAILABLE; + xhdcp2x_tx->xhdcp2x_info.msg_available = 1; + dev_dbg(xhdcp2x_tx->dev, + "HDCP2XTX: H' is Available through CP_IRQ\n\r"); + } + } else if (xhdcp2x_tx->xhdcp2x_internal_timer.reason_id == + HDCP_2_2_AKE_SEND_PAIRING_INFO) { + if (xhdcp2x_tx->xhdcp2x_info.dp_rx_status & + XHDCP2X_RX_STATUS_PAIRING_AVAILABLE) { + xhdcp2x_tx->xhdcp2x_info.dp_rx_status &= + ~XHDCP2X_RX_STATUS_PAIRING_AVAILABLE; + xhdcp2x_tx->xhdcp2x_info.msg_available = 1; + } + } else if (xhdcp2x_tx->xhdcp2x_internal_timer.reason_id == + HDCP_2_2_REP_SEND_RECVID_LIST) { + if (xhdcp2x_tx->xhdcp2x_info.dp_rx_status & + XHDCP2X_RX_STATUS_RPTR_RDY) { + xhdcp2x_tx->xhdcp2x_info.dp_rx_status = + ~XHDCP2X_RX_STATUS_RPTR_RDY; + xhdcp2x_tx->xhdcp2x_info.msg_available = 1; + } + } + if (xhdcp2x_tx->xhdcp2x_info.msg_available) { + xlnx_hdcp_tmrcntr_stop(& + xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0); + xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired = 1; + } + return 0; + } + xlnx_hdcp2x_tx_read_rxstatus(xhdcp2x_tx); + + if ((!ready_bit && ((xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_AVAIL_BYTES_MASK) == expected_size)) || + ((ready_bit && + (xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_READY_MASK)) && + ((xhdcp2x_tx->xhdcp2x_info.rx_status & + XHDCP2X_TX_RXSTATUS_AVAIL_BYTES_MASK) > 0))) { + xlnx_hdcp_tmrcntr_stop(&xhdcp2x_tx->xhdcp2x_internal_timer.tmr_ctr, + XHDCP2X_TX_TIMER_CNTR_0); + xhdcp2x_tx->xhdcp2x_internal_timer.timer_expired = 1; + xhdcp2x_tx->xhdcp2x_info.msg_available = 1; + } + + return 0; + } + + return 0; +} + +void xlnx_hdcp2x_handle_reauth_request(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_REAUTHENTICATE_REQUESTED; + + xlnx_hdcp2x_tx_disable_encryption(xhdcp2x_tx); + xlnx_hdcp2x_cipher_disable(xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher.cipher_coreaddress); + xlnx_hdcp2x_cipher_enable(xhdcp2x_tx->xhdcp2x_hw.xlnxhdcp2x_cipher.cipher_coreaddress); +} + +void xlnx_hdcp2x_tx_auth_failed(struct xlnx_hdcp2x_config *xhdcp2x_tx) +{ + xhdcp2x_tx->xhdcp2x_info.auth_status = + XHDCP2X_TX_AUTHENTICATION_BUSY; + + xhdcp2x_tx->xhdcp2x_info.is_rcvr_hdcp2x_capable = + xlnx_hdcp2x_downstream_capbility(xhdcp2x_tx); +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp2x_tx.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp2x_tx.h @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx Specific HDCP2X driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + */ + +#ifndef _XLNX_HDCP2X_TX_H_ +#define _XLNX_HDCP2X_TX_H_ + +#include +#include +#include +#include +#include +#include "xhdcp2x_tx.h" + +#define XHDCP2X_TX_MAX_ALLOWED_STREAM_MANAGE_CHECKS 128 +#define XHDCP2X_TX_LC128_SIZE 16 +#define XHDCP2X_TX_MAX_STORED_PAIRINGINFO 2 +#define XHDCP2X_TX_TS_WAIT_FOR_STREAM_TYPE 0xFD +#define XHDCP2X_TX_TS_WAIT_FOR_CIPHER GENMASK(7, 1) +#define XHDCP2X_TX_TS_RX_REAUTH_CHECK GENMASK(7, 0) +#define XHDCP2X_TX_RXSTATUS_REAUTH_REQ_MASK BIT(11) +#define XHDCP2X_TX_RXSTATUS_READY_MASK BIT(10) +#define XHDCP2X_TX_RXSTATUS_AVAIL_BYTES_MASK GENMASK(9, 0) +#define XHDCP2X_TX_SRM_RCVID_SIZE HDCP_2_2_RECEIVER_ID_LEN +#define XHDCP2X_TX_SRM_SIGNATURE_SIZE 384 +#define XHDCP2X_TX_MAX_MESSAGE_SIZE (1 + 534) +#define XHDCP2X_TX_INVALID_RXSTATUS GENMASK(15, 0) +#define XHDCP2X_TX_KPUB_DCP_LLC_N_SIZE 384 +#define XHDCP2X_TX_KPUB_DCP_LLC_E_SIZE 1 +#define XHDCP2X_TX_LC128_SIZE 16 +#define XHDCP2X_TX_SRM_SIZE 396 +#define XHDCP2X_TX_SHA_SIZE 256 +#define XHDCP2X_TX_SHA_KEY_LENGTH 64 +#define XHDCP2X_TX_RXCAPS_MASK 0x02 +#define XHDCP2X_TX_CLKDIV_MHZ 1000000 +#define XHDCP2X_TX_CLKDIV_HZ 1000 + +#define XHDCP2X_TX_TIMER_CNTR_0 0 +#define XHDCP2X_TX_TIMER_CNTR_1 1 +#define XHDCP2X_TX_TS_UNDEFINED 0 + +typedef u32 (*xhdcp2x_notify_msg) (void *callbackref, u32 offset, + u8 *buf, u32 size); +typedef void (*xhdcp2x_callback_msg)(void *callbackref); + +enum xhdcp2x_tx_protocol { + XHDCP2X_TX_DP = 0, + XHDCP2X_TX_HDMI = 1 +}; + +enum xhdcp2x_tx_mode { + XHDCP2X_TX_TRANSMITTER = 0, + XHDCP2X_TX_REPEATER = 1, +}; + +/** + * struct xlnx_hdcp2x_hw - HDCP2X subsystem configuration structure + * @xlnxhdcp2x_cipher: HDCP2X cipher engine configuration + * @xlnxhdcp2x_rng: HDCP2X random number generator configuration + * @hdcp2xcore_address: HDCP2X core address + * @tx_mode: HDCP Transmitter or Repeater + * @protocol: Protocol type, DP or HDMI + */ +struct xlnx_hdcp2x_hw { + struct xlnx_hdcp2x_cipher_hw xlnxhdcp2x_cipher; + struct xlnx_hdcp2x_rng_hw xlnxhdcp2x_rng; + void __iomem *hdcp2xcore_address; + enum xhdcp2x_tx_mode tx_mode; + enum xhdcp2x_tx_protocol protocol; +}; + +enum xhdcp2x_tx_content_stream_type { + XHDCP2X_STREAMTYPE_0 = 0, + XHDCP2X_STREAMTYPE_1 = 1, +}; + +enum xhdcp2x_tx_authtype { + XHDCP2X_TX_INCOMPATIBLE_RX = 0, + XHDCP2X_TX_AUTHENTICATION_BUSY = 1, + XHDCP2X_TX_AUTHENTICATED = 2, + XHDCP2X_TX_UNAUTHENTICATED = 3, + XHDCP2X_TX_REAUTHENTICATE_REQUESTED = 4, + XHDCP2X_TX_DEVICE_IS_REVOKED = 5, + XHDCP2X_TX_NO_SRM_LOADED = 6 +}; + +enum xhdcp2x_tx_rx_status { + XHDCP2X_RX_STATUS_RPTR_RDY = 0x01, + XHDCP2X_RX_STATUS_H_PRIME_AVAILABLE = 0x02, + XHDCP2X_RX_STATUS_PAIRING_AVAILABLE = 0x04, + XHDCP2X_RX_STATUS_REAUTH_REQ = 0x08, + XHDCP2X_RX_STATUS_LINK_INTEGRITY_FAIL = 0x10 +}; + +/** + * struct xhdcp2x_tx_internal_timer - Current state and data used for internal timer + * @tmr_ctr: Hardware timer configuration structure + * @initial_ticks: Keep track of the start value of the timer. + * @reason_id: Keep track of why the timer was started (message or status checking) + * @timer_expired: Expiration flag set when the hardware timer has interrupted. + */ +struct xhdcp2x_tx_internal_timer { + struct xlnx_hdcp_timer_config tmr_ctr; + u32 initial_ticks; + u8 reason_id; + bool timer_expired; + +}; + +struct xhdcp2x_tx_msg { + u8 msg; + union hdcp2x_tx_msg_type msg_type; +}; + +/** + * struct xhdcp2x_tx_internal_info - This structure contains configuration information + * for the device. + * @pairing_info: HDCP2X pairing info + * @curr_state: Current state of internal state machine + * @prev_state: Previous state of internal state machine + * @auth_status: The result of internal state machine transaction + * @content_stream_type: Content stream type used with Content Stream Management + * @state_context: Context used internally by the state machine + * @M: Calculated M value + * @r_tx: Internal used rtx + * @r_rx: Internal used rrx + * @rn: Internal used rn + * @txcaps: HDCP tx capabilities + * @seq_num_v: Sequence number V used with Received Id list + * @seq_num_m: Sequence number M used with Content Stream Management + * @prev_seq_num_m: Previous sequence number M used with Content Stream Management + * @polling_value: The currently used polling interval value for a message + * @content_strm_mng_chk_cntr: Keeps track of Content Stream Management checks performed + * @rx_status: HDCP RX status read on timer interrupt + * @lc_counter: Locality may attempt 1024 times + * @dp_rx_status: HDCP RX status read on CP_IRQ interrupt + * @is_content_stream_type_set:Content stream type is set + * @is_enabled:Is HDCP TX enabled state machine is active + * @is_rcvr_hdcp2x_capable: Is receiver a HDCP2x capable + * @is_rcvr_repeater: Is the receiver a HDCP repeater + * @is_revoc_list_valid: Is revocation list valid + * @is_device_revoked: Is a device listed in the revocation list + * @msg_available: Message is available for reading + */ +struct xhdcp2x_tx_internal_info { + struct hdcp2x_tx_pairing_info pairing_info[XHDCP2X_TX_MAX_STORED_PAIRINGINFO]; + enum hdcp2x_tx_state curr_state; + enum hdcp2x_tx_state prev_state; + enum xhdcp2x_tx_authtype auth_status; + enum xhdcp2x_tx_content_stream_type content_stream_type; + void *state_context; + u8 M[32]; + u8 r_tx[8]; + u8 r_rx[8]; + u8 rn[8]; + u8 txcaps[3]; + u32 seq_num_v; + u32 seq_num_m; + u32 prev_seq_num_m; + u32 polling_value; + u16 content_strm_mng_chk_cntr; + u16 rx_status; + u16 lc_counter; + u8 dp_rx_status; + bool is_content_stream_type_set; + bool is_enabled; + bool is_rcvr_hdcp2x_capable; + bool is_rcvr_repeater; + bool is_revoc_list_valid; + bool is_device_revoked; + bool msg_available; +}; + +struct xhdcp2x_tx_callbacks { + int (*rd_handler)(void *interface_ref, u32 offset, u8 *buf, u32 size); + int (*wr_handler)(void *interface_ref, u32 offset, u8 *buf, u32 size); + void (*notify_handler)(void *interface_ref, u32 notification); +}; + +/** + * struct xlnx_hdcp2x_config - This structure contains HDCP2X driver + * configuration information + * @dev: device information + * @xhdcp2x_hw: Configuration HDCP2x hardware + * @xhdcp2x_pairing_info: HDCP2X pairing information + * @xhdcp2x_revoc_list: HDCP2X revocation list + * @xhdcp2x_topology: HDCP2x topology information + * @xhdcp2x_info: Provides the control and status of internal driver parameters + * @xhdcp2x_internal_timer: Internal timer parameters + * @handlers: Callback handlers + * @interface_ref: Interface reference + * @interface_base: Interface base + * @msg_buffer: Message buffer for messages that are sent/received + * @lc128key: LC128 encryption key + * @msg_buffer: Message buffer to store HDCP input/output messages + * @srmkey: SRM encryption key + * @is_hdmi: Interface type HDMI or DP + * @txcaps: transmitter capabilities + * @lane_count: Number of lanes data to be encrypted + * @is_repeater: Says whether downstream is repeater or receiver + */ +struct xlnx_hdcp2x_config { + struct device *dev; + struct xlnx_hdcp2x_hw xhdcp2x_hw; + struct hdcp2x_tx_pairing_info xhdcp2x_pairing_info; + struct hdcp2x_tx_revoclist xhdcp2x_revoc_list; + struct hdcp2x_tx_topology xhdcp2x_topology; + struct xhdcp2x_tx_internal_info xhdcp2x_info; + struct xhdcp2x_tx_internal_timer xhdcp2x_internal_timer; + struct xhdcp2x_tx_callbacks handlers; + void *interface_ref; + void __iomem *interface_base; + u8 msg_buffer[XHDCP2X_TX_MAX_MESSAGE_SIZE]; + u8 *lc128key; + u8 *srmkey; + u8 is_hdmi; + u8 *txcaps; + u8 lane_count; + bool is_repeater; +}; + +struct hdcp2x_tx_pairing_info + *xlnx_hdcp2x_tx_update_pairinginfo(struct xlnx_hdcp2x_config *xhdcp2x_tx, + struct hdcp2x_tx_pairing_info *pairing_info, u8 ready); +struct hdcp2x_tx_pairing_info *xlnx_hdcp2x_tx_get_pairing_info(struct xlnx_hdcp2x_config + *xhdcp2x_tx, const u8 *rcvid); +int xlnx_hdcp2x_tx_init(struct xlnx_hdcp2x_config *xhdcp2x_tx, bool is_repeater); +int xlnx_hdcp2x_task_monitor(struct xlnx_hdcp2x_config *xhdcp2x_tx); +int xlnx_hdcp2x_tx_reset(struct xlnx_hdcp2x_config *xhdcp2x_tx); +int xlnx_hdcp2x_tx_verify_certificate(const struct hdcp2x_tx_cert_rx *rx_certificate, + const u8 *dcp_cert_nvalue, int dcp_cert_nsize, + const u8 *dcp_cert_evalue, int dcp_cert_esize); +int xlnx_hdcp2x_tx_write_akenostored_km(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const struct hdcp2x_tx_pairing_info *pairing_info, + const struct hdcp2x_tx_cert_rx *cert_ptr); +int xlnx_hdcp2x_tx_write_rptr_auth_send_ack(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *v_ptr); +int xlnx_hdcp2x_tx_write_ake_storedkm(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const struct hdcp2x_tx_pairing_info *hdcp2x_tx_pairing_info); +int xlnx_hdcp2x_tx_read_msg(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 msg_id); +int xlnx_hdcp2x_tx_write_lcinit(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *rn_ptr); +int xlnx_hdcp2x_tx_write_type_value(struct xlnx_hdcp2x_config *xhdcp2x_tx); +int xlnx_hdcp2x_tx_write_ske_send_eks(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *edkey_ptr, const u8 *riv_ptr); +int xlnx_hdcp2x_tx_write_ake_init(struct xlnx_hdcp2x_config *xhdcp2x_tx); +int xlnx_hdcp2x_tx_encryptedkm(const struct hdcp2x_tx_cert_rx *rx_certificate, + const u8 *km_ptr, u8 *masking_seed, u8 *encrypted_km); +int xlnx_hdcp2x_tx_wait_for_receiver(struct xlnx_hdcp2x_config *xhdcp2x_tx, + int expected_size, u8 ready_bit); +int xlnx_hdcp2x_tx_rptr_auth_stream_mng(struct xlnx_hdcp2x_config *xhdcp2x_tx); +int hdcp2x_tx_protocol_authenticate_sm(struct xlnx_hdcp2x_config *hdcp2x_tx); +int xlnx_hdcp2x_verify_srm(const u8 *srm, int srm_size, const u8 *dcp_cert_nvalue, + int dcp_cert_nsize, const u8 *dcp_cert_evalue, int dcp_cert_esize); +int xlnx_hdcp2x_loadkeys(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 *srm, u8 *lc128); +void xlnx_start_hdcp2x_engine(struct xlnx_hdcp2x_config *xhdcp2x_tx); +void xlnx_hdcp2x_tx_timer_init(struct xlnx_hdcp2x_config *xhdcp2x_tx, + struct xlnx_hdcp_timer_config *tmr_cntrl); +void xlnx_hdcp2x_tx_auth_failed(struct xlnx_hdcp2x_config *xhdcp2x_tx); +void xlnx_hdcp2x_handle_reauth_request(struct xlnx_hdcp2x_config *xhdcp2x_tx); +void xlnx_hdcp2x_tx_generatekm(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 *kmptr); +void xlnx_hdcp2x_tx_invalidate_paring_info(struct xlnx_hdcp2x_config *xhdcp2x_tx, + const u8 *rcvid); +void xlnx_hdcp2x_tx_read_rxstatus(struct xlnx_hdcp2x_config *xhdcp2x_tx); +void xlnx_hdcp2x_tx_process_cp_irq(struct xlnx_hdcp2x_config *xhdcp2x_tx); +void xlnx_hdcp2x_tx_timer_handler(void *callbackref, u8 tmr_cnt_number); +void xlnx_hdcp2x_tx_compute_edkey_ks(const u8 *rn, const u8 *km, const u8 *ks, const u8 *r_rx, + const u8 *r_tx, u8 *encrypted_ks); +void xlnx_hdcp2x_tx_compute_lprime(const u8 *rn, const u8 *km, const u8 *r_rx, const u8 *r_tx, + u8 *lprime); +void xlnx_hdcp2x_tx_compute_v(const u8 *rn, const u8 *r_rx, const u8 *rx_info, + const u8 *r_tx, const u8 *rcvid_list, const u8 rcvid_count, + const u8 *seq_num_v, const u8 *km, u8 *hash_v); +void xlnx_hdcp2x_tx_compute_m(const u8 *rn, const u8 *r_rx, const u8 *r_tx, + const u8 *stream_id_type, const u8 *k, + const u8 *seq_num_m, const u8 *km, u8 *m_hash); +void xlnx_hdcp2x_tx_compute_hprime(const u8 *r_rx, const u8 *rxcaps, + const u8 *r_tx, const u8 *txcaps, + const u8 *km, u8 *hprime); +void xlnx_hdcp2x_tx_disable_encryption(struct xlnx_hdcp2x_config *xhdcp2x_tx); +void xlnx_hdcp2x_tx_start_timer(struct xlnx_hdcp2x_config *xhdcp2x_tx, + u32 timeout, u8 reason_id); +void xlnx_hdcp2x_tx_enable_encryption(struct xlnx_hdcp2x_config *xhdcp2x_tx); +u8 xlnx_hdcp2x_tx_is_device_revoked(struct xlnx_hdcp2x_config *xhdcp2x_tx, u8 *rcvid); +const u8 *xlnx_hdcp2x_tx_get_publickey(struct xlnx_hdcp2x_config *xhdcp2x_tx); +bool xlnx_hdcp2x_downstream_capbility(struct xlnx_hdcp2x_config + *xhdcp2x_tx); +#endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_sha1.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_sha1.c @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * xlnx_hdcp_sha1.c + * + * Description: + * This file implements the Secure Hashing Algorithm 1 as + * defined in FIPS PUB 180-1 published April 17, 1995. + * + * The SHA-1, produces a 160-bit message digest for a given + * data stream. It should take about 2**n steps to find a + * message with the same digest as a given message and + * 2**(n/2) to find any two messages with the same digest, + * when n is the digest size in bits. Therefore, this + * algorithm can serve as a means of providing a + * "fingerprint" for a message. + * + * Caveats: + * SHA-1 is designed to work with messages less than 2^64 bits + * long. Although SHA-1 allows a message digest to be generated + * for messages of any number of bits less than 2^64, this + * implementation only works with messages with a length that is + * a multiple of the size of an 8-bit character. + * + */ + +/* Some part of Code for sha calculations are modified according to Xilinx standards */ + +/* Reference : https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/NIST.FIPS.180.pdf */ + +#include +#include "xlnx_hdcp_sha1.h" + +/* + * Define the SHA1 circular left shift macro + */ +#define xlnx_sha1_circular_shift(bits, word) \ +({\ + typeof(bits) (_x) = (bits); \ + typeof(word) (_y) = (word); \ + (((_y) << (_x)) | ((_y) >> (32 - (_x)))); \ +}) + +/** + * xlnx_sha1_reset - This function will initialize the xlnx_sha1_context in + * preparation for computing a new SHA1 message digest + * @context: SHA context structure + * return: success on reset or SHA error code otherwise + */ +int xlnx_sha1_reset(struct xlnx_sha1_context *context) +{ + if (!context) + return XLNX_SHA_NULL; + + context->length_low = 0; + context->length_high = 0; + context->msg_block_index = 0; + + memset(context->message_block, 0, MESSAGE_BLOCK_SIZE); + context->intermediate_hash[0] = SHA1_H0; + context->intermediate_hash[1] = SHA1_H1; + context->intermediate_hash[2] = SHA1_H2; + context->intermediate_hash[3] = SHA1_H3; + context->intermediate_hash[4] = SHA1_H4; + + context->computed = 0; + context->corrupted = 0; + + return XLNX_SHA_SUCCESS; +} + +/** + * xlnx_sha1_result - This function will return the 160-bit message + * digest into the message_digest array provided by the caller. + * NOTE: The first octet of hash is stored in the 0th element, + * the last octet of hash in the 19th element + * @context: SHA context structure + * @message_digest: Message digest output + * return: success when message digest is correct or + * SHA error code otherwise + */ +int xlnx_sha1_result(struct xlnx_sha1_context *context, + u8 message_digest[SHA1_HASH_SIZE]) +{ + int i; + + if (!context || !message_digest) + return XLNX_SHA_NULL; + if (context->corrupted) + return context->corrupted; + if (!context->computed) { + xlnx_sha1_pad_message(context); + for (i = 0; i < MESSAGE_BLOCK_SIZE; ++i) { + /* message may be sensitive, clear it out */ + context->message_block[i] = 0; + } + context->length_low = 0; /* and clear length */ + context->length_high = 0; + context->computed = 1; + } + for (i = 0; i < SHA1_HASH_SIZE; ++i) { + message_digest[i] = context->intermediate_hash[i >> 2] + >> BITS_PER_BYTE * (SHA_INTERMEDIATE_HASH_H3 - + (i & SHA_INTERMEDIATE_HASH_H3)); + } + + return XLNX_SHA_SUCCESS; +} + +/** + * xlnx_sha1_process_message_block - This function will process the next + * 512 bits of the message stored in the message_block array. + * NOTE: Many of the variable names in this code, especially the + * single character names, were used because those were the + * names used in the publication. + * @context: SHA context structure + * return: none + */ +void xlnx_sha1_process_message_block(struct xlnx_sha1_context *context) +{ + const unsigned int K[] = { + /* Constants defined in SHA-1 */ + K1, + K2, + K3, + K4 + }; + int t; /* Loop counter */ + unsigned int temp; /* Temporary word value */ + unsigned int word_seq[SHA_MAX_HASH_OPERATIONS]; /* Word sequence */ + unsigned int A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array word_seq + */ + for (t = 0; t < SHA1_WORKSPACE_WORDS; t++) { + word_seq[t] = context->message_block[t * 4] << 24; + word_seq[t] |= context->message_block[t * 4 + 1] << 16; + word_seq[t] |= context->message_block[t * 4 + 2] << 8; + word_seq[t] |= context->message_block[t * 4 + 3]; + } + for (t = SHA1_WORKSPACE_WORDS; t < SHA_MAX_HASH_OPERATIONS; t++) + word_seq[t] = xlnx_sha1_circular_shift(1, + word_seq[t - 3] ^ word_seq[t - 8] ^ + word_seq[t - 14] ^ word_seq[t - 16]); + A = context->intermediate_hash[0]; + B = context->intermediate_hash[1]; + C = context->intermediate_hash[2]; + D = context->intermediate_hash[3]; + E = context->intermediate_hash[4]; + + for (t = 0; t < SHA1_DIGEST_SIZE; t++) { + temp = xlnx_sha1_circular_shift(5, A) + + ((B & C) | ((~B) & D)) + E + + word_seq[t] + K[0]; + E = D; + D = C; + C = xlnx_sha1_circular_shift(SHA_BITS_TO_ROTATE, B); + B = A; + A = temp; + } + for (t = SHA1_DIGEST_SIZE; t < SHA_BITS_TO_ROTATE_ROUND2; t++) { + temp = xlnx_sha1_circular_shift(5, A) + (B ^ C ^ D) + E + word_seq[t] + K[1]; + E = D; + D = C; + C = xlnx_sha1_circular_shift(SHA_BITS_TO_ROTATE, B); + B = A; + A = temp; + } + for (t = SHA_BITS_TO_ROTATE_ROUND2; t < SHA_BITS_TO_ROTATE_ROUND3; t++) { + temp = xlnx_sha1_circular_shift(5, A) + + ((B & C) | (B & D) | (C & D)) + E + + word_seq[t] + K[2]; + E = D; + D = C; + C = xlnx_sha1_circular_shift(SHA_BITS_TO_ROTATE, B); + B = A; + A = temp; + } + for (t = SHA_BITS_TO_ROTATE_ROUND2; t < SHA_MAX_HASH_OPERATIONS; t++) { + temp = xlnx_sha1_circular_shift(5, A) + (B ^ C ^ D) + E + word_seq[t] + K[3]; + E = D; + D = C; + C = xlnx_sha1_circular_shift(SHA_BITS_TO_ROTATE, B); + B = A; + A = temp; + } + + context->intermediate_hash[0] += A; + context->intermediate_hash[1] += B; + context->intermediate_hash[2] += C; + context->intermediate_hash[3] += D; + context->intermediate_hash[4] += E; + + context->msg_block_index = 0; +} + +/** + * xlnx_sha1_input - This function accepts an array of octets as the + * next portion of the message + * @context: SHA context structure + * @message_array: An array of characters represetning the next + * portion of the message + * @length: The length of the message in message_array + * return: success when new input is added to the SHA message or + * SHA error code otherwise + */ +int xlnx_sha1_input(struct xlnx_sha1_context *context, + const unsigned char *message_array, + unsigned int length) +{ + if (!length) + return XLNX_SHA_SUCCESS; + if (!context || !message_array) + return XLNX_SHA_NULL; + if (context->computed) { + context->corrupted = XLNX_SHA_STATE_ERROR; + return XLNX_SHA_STATE_ERROR; + } + + if (context->corrupted) + return context->corrupted; + while (length-- && !context->corrupted) { + context->message_block[context->msg_block_index++] = + (*message_array & 0xFF); + context->length_low += 8; + if (context->length_low == 0) { + context->length_high++; + if (context->length_high == 0) { + /* Message is too long */ + context->corrupted = 1; + } + } + if (context->msg_block_index == MESSAGE_BLOCK_SIZE) + xlnx_sha1_process_message_block(context); + + message_array++; + } + + return XLNX_SHA_SUCCESS; +} + +/** + * xlnx_sha1_pad_message - According to the standard, the message must be + * padded to an even 512 bits.The first padding bit must be a '1'. + * The last 64 bits represent the length of the original message. + * All bits in between should be 0.This function will pad the message + * according to those rules by filling the Message_Block array + * accordingly. It will also call the ProcessMessageBlock function + * provided appropriately. When it returns, it can be assumed that + * the message digest has been computed. + * @context: SHA context structure + * return: None + */ +void xlnx_sha1_pad_message(struct xlnx_sha1_context *context) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->msg_block_index > 55) { + context->message_block[context->msg_block_index++] = 0x80; + while (context->msg_block_index < SHA1_BLOCK_SIZE) + context->message_block[context->msg_block_index++] = 0; + xlnx_sha1_process_message_block(context); + while (context->msg_block_index < 56) + context->message_block[context->msg_block_index++] = 0; + } else { + context->message_block[context->msg_block_index++] = 0x80; + while (context->msg_block_index < 56) + context->message_block[context->msg_block_index++] = 0; + } + /* + * Store the message length as the last 8 octets. + */ + context->message_block[56] = context->length_high >> 24; + context->message_block[57] = context->length_high >> 16; + context->message_block[58] = context->length_high >> 8; + context->message_block[59] = context->length_high; + context->message_block[60] = context->length_low >> 24; + context->message_block[61] = context->length_low >> 16; + context->message_block[62] = context->length_low >> 8; + context->message_block[63] = context->length_low; + + xlnx_sha1_process_message_block(context); +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_sha1.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_sha1.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * xlnx_hdcp_sha1.h + * + * Description: + * This is the header file for code which implements the Secure + * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published + * April 17, 1995. + * + * Many of the variable names in this code, especially the + * single character names, were used because those were the names + * used in the publication. + * + * Please read the file xlnx_hdcp_sha1.c for more information. + * + */ + +#ifndef _XLNX_HDCP_SHA1_H_ +#define _XLNX_HDCP_SHA1_H_ + +#include +#include + +enum { + XLNX_SHA_SUCCESS = 0, + XLNX_SHA_NULL = 1, /* Null pointer parameter */ + XLNX_SHA_INPUT_TOO_LONG = 2, /* input data too long */ + XLNX_SHA_STATE_ERROR = 3 /* called Input after Result */ +}; + +#define SHA1_HASH_SIZE 20 +#define MESSAGE_BLOCK_SIZE 64 +#define SHA_INTERMEDIATE_HASH_H3 3 +#define SHA_MAX_HASH_OPERATIONS 80 +#define SHA_BITS_TO_ROTATE 30 +#define SHA_BITS_TO_ROTATE_ROUND2 40 +#define SHA_BITS_TO_ROTATE_ROUND3 60 + +#define K1 0x5a827999 +#define K2 0x6ed9eba1 +#define K3 0x8f1bbcdc +#define K4 0xca62c1d6 + +/** + * struct xlnx_sha1_context - This structure holds the context + * information for the SHA-1 hashing operation. + * @intermediate_hash: Message digest + * @length_low: Message length in bits + * @length_high: Message length in bits + * @msg_block_index: Index into message block array + * @message_block: 512-bit message block array + * @computed: Indicates the message digest is computed + * @corrupted: Indicates the message digest is corrupted + */ +struct xlnx_sha1_context { + unsigned int intermediate_hash[SHA1_HASH_SIZE / 4]; + unsigned int length_low; + unsigned int length_high; + u16 msg_block_index; + unsigned char message_block[MESSAGE_BLOCK_SIZE]; + int computed; + int corrupted; +}; + +int xlnx_sha1_reset(struct xlnx_sha1_context *context); +int xlnx_sha1_input(struct xlnx_sha1_context *context, const unsigned char *msg, + unsigned int length); +int xlnx_sha1_result(struct xlnx_sha1_context *context, + unsigned char message_digest[SHA1_HASH_SIZE]); +void xlnx_sha1_pad_message(struct xlnx_sha1_context *context); +void xlnx_sha1_process_message_block(struct xlnx_sha1_context *context); + +#endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_tx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_tx.c @@ -0,0 +1,461 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx HDCP Transmitter Interface driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + * + * This driver acts like an interface layer between HDCP1X and HDCP2X protocols + * for Xilinx transmitter subsystem devices. + * + * This driver initializes the HDCP IP and its internal modules based on + * downstream capabilities and starts Authentication. + * + * Currently HDCP2X protocol and its functionalities only enabled in this driver. + */ + +#include +#include +#include "xlnx_hdcp_tx.h" +#include "xlnx_hdcp1x_tx.h" +#include "xlnx_hdcp2x_tx.h" + +#define XDPTX_TIMER_CLOCK_FREQ_HZ 99999001U + +void xlnx_hdcptx_read_ds_sink_capability(struct xlnx_hdcptx *xtxhdcp) +{ + int status = 0; + + if (xtxhdcp->hdcp2xenable) { + if (xlnx_hdcp2x_downstream_capbility(xtxhdcp->xhdcp2x)) { + xtxhdcp->hdcp_protocol = XHDCPTX_HDCP_2X; + status = true; + } + } + if (xtxhdcp->hdcp1xenable && !status) { + if (xlnx_hdcp1x_downstream_capbility(xtxhdcp->xhdcp1x)) { + xtxhdcp->hdcp_protocol = XHDCPTX_HDCP_1X; + status = true; + } + } + if (!status) { + xtxhdcp->hdcp_protocol = XHDCPTX_HDCP_NONE; + + if (xtxhdcp->hdcp1xenable) + xlnx_hdcp1x_tx_start_timer(xtxhdcp->xhdcp1x, + XHDMI_HDCP1X_WAIT_FOR_ACTIVE_RECEIVER, 0); + } +} +EXPORT_SYMBOL_GPL(xlnx_hdcptx_read_ds_sink_capability); + +static void hdcp_task_monitor_fun(struct work_struct *work) +{ + struct xlnx_hdcptx *xtxhdcp; + + xtxhdcp = container_of(work, struct xlnx_hdcptx, hdcp_task_monitor.work); + + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_NONE) + xlnx_hdcptx_read_ds_sink_capability(xtxhdcp); + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_2X) { + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + + mutex_lock(&xtxhdcp->hdcptx_mutex); + xtxhdcp->auth_status = xlnx_hdcp2x_task_monitor(xhdcp2x); + if (xhdcp2x->handlers.notify_handler) + xhdcp2x->handlers.notify_handler(xhdcp2x->interface_ref, + xtxhdcp->auth_status); + schedule_delayed_work(&xtxhdcp->hdcp_task_monitor, 0); + mutex_unlock(&xtxhdcp->hdcptx_mutex); + } else if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_1X) { + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + mutex_lock(&xtxhdcp->hdcptx_mutex); + xtxhdcp->auth_status = xlnx_hdcp1x_task_monitor(xhdcp1x); + if (xhdcp1x->handlers.notify_handler) + xhdcp1x->handlers.notify_handler(xhdcp1x->interface_ref, + xtxhdcp->auth_status); + schedule_delayed_work(&xtxhdcp->hdcp_task_monitor, 0); + mutex_unlock(&xtxhdcp->hdcptx_mutex); + } else { + dev_dbg(xtxhdcp->dev, "Task Monitor is Failed\n"); + dev_dbg(xtxhdcp->dev, "Unsupported protocol\n"); + } +} + +void xlnx_hdcp_tx_process_cp_irq(struct xlnx_hdcptx *xtxhdcp) +{ + if (xtxhdcp->hdcp2xenable) { + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_2X) + xlnx_hdcp2x_tx_process_cp_irq(xhdcp2x); + } +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_process_cp_irq); + +/** + * xlnx_hdcp_tx_init - Initialize HDCP transmitter based on hardware selection + * and downstream capability + * @dev: device structure + * @protocol_ref: DP/HDMI structure reference + * @xtxhdcp: Xilinx HDCP core driver structure + * @hdcp_base_address: HDCP core address + * @is_repeater: Repeater selection + * @hdcp_type: HDCP protocol selection + * @lane_count: Number of lanes data to be encrypted + * @hw_protocol: Interface type HDMI or DP + * @key_base_address: HDCP Key Management base address + * return: HDCP 1x/2x driver structure if success or return memory allocation error + */ +void *xlnx_hdcp_tx_init(struct device *dev, void *protocol_ref, + struct xlnx_hdcptx *xtxhdcp, void __iomem *hdcp_base_address, + u8 is_repeater, enum xlnx_hdcptx_protocol_type hdcp_type, u8 lane_count, + int hw_protocol, struct regmap *key_base_address) +{ + struct xlnx_hdcp2x_config *xhdcp2x; + struct xlnx_hdcp1x_config *xhdcp1x; + void *hdcp_drv_address; + int ret; + + if (hdcp_type == XHDCPTX_HDCP_2X) { + xhdcp2x = devm_kzalloc(dev, sizeof(*xhdcp2x), GFP_KERNEL); + if (!xhdcp2x) + return ERR_PTR(-ENOMEM); + + hdcp_drv_address = xhdcp2x; + xhdcp2x->xhdcp2x_hw.hdcp2xcore_address = + (void __iomem *)hdcp_base_address; + + xhdcp2x->xhdcp2x_hw.protocol = hw_protocol; + xhdcp2x->dev = dev; + xhdcp2x->interface_ref = protocol_ref; + xhdcp2x->interface_base = hdcp_base_address; + xhdcp2x->is_repeater = is_repeater ? 1 : 0; + xhdcp2x->lane_count = lane_count; + + ret = xlnx_hdcp2x_tx_init(xhdcp2x, xhdcp2x->is_repeater); + if (ret < 0) { + dev_err(xhdcp2x->dev, "Failed to initialize HDCP2X engine\n"); + goto hdcp2x_error; + } + } + if (hdcp_type == XHDCPTX_HDCP_1X) { + xhdcp1x = devm_kzalloc(dev, sizeof(*xhdcp1x), GFP_KERNEL); + if (!xhdcp1x) + return ERR_PTR(-ENOMEM); + + hdcp_drv_address = xhdcp1x; + xhdcp1x->protocol = hw_protocol; + xhdcp1x->dev = dev; + xhdcp1x->interface_ref = protocol_ref; + xhdcp1x->interface_base = hdcp_base_address; + xhdcp1x->is_repeater = is_repeater ? 1 : 0; + xhdcp1x->lane_count = lane_count; + xhdcp1x->hdcp1x_keymgmt_base = key_base_address; + ret = xlnx_hdcp1x_tx_init(xhdcp1x, xhdcp1x->is_repeater); + if (ret < 0) { + dev_err(xhdcp1x->dev, "Failed to initialize HDCP1X engine\n"); + goto hdcp1x_error; + } + } + if (hdcp_type == XHDCPTX_HDCP_NONE) + return ERR_PTR(-ENOMEM); + + mutex_init(&xtxhdcp->hdcptx_mutex); + INIT_DELAYED_WORK(&xtxhdcp->hdcp_task_monitor, hdcp_task_monitor_fun); + + return (void *)hdcp_drv_address; + +hdcp1x_error: + devm_kfree(dev, xhdcp1x); + +hdcp2x_error: + devm_kfree(dev, xhdcp2x); + + return ERR_PTR(-ENOMEM); +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_init); + +/** + * xlnx_hdcp_timer_init - This function initializes timer submodule + * and driver structure parameters + * @dev: device structure + * @timer_base_address: Xilinx timer core address + * return: timer driver structure address if success or return memory + * allocation error + */ +void *xlnx_hdcp_timer_init(struct device *dev, void __iomem *timer_base_address) +{ + struct xlnx_hdcp_timer_config *xhdcptmr; + int ret; + + xhdcptmr = devm_kzalloc(dev, sizeof(*xhdcptmr), GFP_KERNEL); + if (!xhdcptmr) + return ERR_PTR(-ENOMEM); + + xhdcptmr->hw_config.coreaddress = (void __iomem *)timer_base_address; + xhdcptmr->hw_config.sys_clock_freq = XDPTX_TIMER_CLOCK_FREQ_HZ; + + ret = xlnx_hdcp_tmrcntr_init(xhdcptmr); + if (ret < 0) + goto error; + + return xhdcptmr; + +error: + devm_kfree(dev, xhdcptmr); + + return ERR_PTR(-ENOMEM); +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_timer_init); + +int xlnx_hdcp_tx_exit(struct xlnx_hdcptx *xtxhdcp) +{ + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + if (xtxhdcp->hdcp2xenable) { + if (xtxhdcp->xhdcp2x) { + devm_kfree(xtxhdcp->dev, xhdcp2x); + } else { + dev_err(xtxhdcp->dev, "HDCP2X is not initialized\n"); + goto hdcp_error; + } + } + if (xtxhdcp->hdcp1xenable) { + if (xtxhdcp->xhdcp1x) { + devm_kfree(xtxhdcp->dev, xhdcp1x); + } else { + dev_err(xtxhdcp->dev, "Hdcp1x is not initialized\n"); + goto hdcp_error; + } + } + return 0; + +hdcp_error: + return -EINVAL; +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_exit); + +void xlnx_hdcp_tx_timer_exit(struct xlnx_hdcptx *xtxhdcp) +{ + struct xlnx_hdcp_timer_config *xhdcptmr = xtxhdcp->xhdcptmr; + + if (xtxhdcp->xhdcptmr) + devm_kfree(xtxhdcp->dev, xhdcptmr); +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_timer_exit); + +int xlnx_hdcp_tx_set_keys(struct xlnx_hdcptx *xtxhdcp, const u8 *data) +{ + int ret = 0; + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + u8 local_srm[XHDCP2X_TX_SRM_SIZE]; + u8 local_lc128[XHDCP2X_TX_LC128_SIZE]; + u8 local_buf[XHDCP1X_TX_ENCRYPTION_KEY_SIZE]; + + memcpy(local_buf, data, XHDCP1X_TX_ENCRYPTION_KEY_SIZE); + memcpy(local_lc128, data + XHDCP1X_TX_ENCRYPTION_KEY_SIZE, XHDCP2X_TX_LC128_SIZE); + memcpy(local_srm, + data + XHDCP1X_TX_ENCRYPTION_KEY_SIZE + XHDCP2X_TX_LC128_SIZE, XHDCP2X_TX_SRM_SIZE); + + if (xtxhdcp->hdcp2xenable) { + ret = xlnx_hdcp2x_loadkeys(xhdcp2x, local_srm, local_lc128); + if (ret < 0) + return -EINVAL; + } + if (xtxhdcp->hdcp1xenable) { + ret = xlnx_hdcp1x_set_keys(xhdcp1x, local_buf); + if (ret < 0) + return -EINVAL; + } + + xtxhdcp->is_enckey_available = true; + + return ret; +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_set_keys); + +int xlnx_hdcp_tx_reset(struct xlnx_hdcptx *xtxhdcp) +{ + int ret; + + if (!(xtxhdcp->hdcp2xenable || xtxhdcp->hdcp1xenable)) + return -EINVAL; + + if (xtxhdcp->hdcp2xenable) { + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + + cancel_delayed_work_sync(&xtxhdcp->hdcp_task_monitor); + xtxhdcp->hdcp_protocol = XHDCPTX_HDCP_NONE; + mutex_lock(&xtxhdcp->hdcptx_mutex); + + ret = xlnx_hdcp2x_tx_reset(xhdcp2x); + if (ret < 0) { + mutex_unlock(&xtxhdcp->hdcptx_mutex); + return -EINVAL; + } + mutex_unlock(&xtxhdcp->hdcptx_mutex); + } + if (xtxhdcp->hdcp1xenable) { + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + cancel_delayed_work_sync(&xtxhdcp->hdcp_task_monitor); + xtxhdcp->hdcp_protocol = XHDCPTX_HDCP_NONE; + mutex_lock(&xtxhdcp->hdcptx_mutex); + + ret = xlnx_hdcp1x_tx_reset(xhdcp1x); + if (ret < 0) { + mutex_unlock(&xtxhdcp->hdcptx_mutex); + return -EINVAL; + } + mutex_unlock(&xtxhdcp->hdcptx_mutex); + } + + return 0; +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_reset); + +static void xlnx_hcdp_tx_timer_callback(void *xtxhdcptr, u8 tmrcntr_number) +{ + struct xlnx_hdcptx *xtxhdcp = xtxhdcptr; + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + if (xtxhdcp->hdcp2xenable) { + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_2X) { + mutex_lock(&xtxhdcp->hdcptx_mutex); + xlnx_hdcp2x_tx_timer_handler((void *)xhdcp2x, + tmrcntr_number); + mutex_unlock(&xtxhdcp->hdcptx_mutex); + + return; + } + } + if (xtxhdcp->hdcp1xenable) { + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_NONE) { + schedule_delayed_work(&xtxhdcp->hdcp_task_monitor, 0); + } else if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_1X) { + mutex_lock(&xtxhdcp->hdcptx_mutex); + xlnx_hdcp1x_tx_timer_handler((void *)xhdcp1x, tmrcntr_number); + mutex_unlock(&xtxhdcp->hdcptx_mutex); + } + + return; + } +} + +int xlnx_start_hdcp_engine(struct xlnx_hdcptx *xtxhdcp, u8 lanecount) +{ + if (!(xtxhdcp->hdcp2xenable || xtxhdcp->hdcp1xenable)) + return -EINVAL; + + if (!xtxhdcp->is_enckey_available) + return -EINVAL; + + if (xtxhdcp->hdcp2xenable) { + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + + xlnx_hdcptx_read_ds_sink_capability(xtxhdcp); + + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_2X) { + xlnx_hdcp2x_tx_timer_init(xhdcp2x, xtxhdcp->xhdcptmr); + xlnx_hdcp_tmrcntr_set_handler(xtxhdcp->xhdcptmr, + xlnx_hcdp_tx_timer_callback, + (void *)xtxhdcp); + xhdcp2x->lane_count = lanecount; + xlnx_start_hdcp2x_engine(xhdcp2x); + schedule_delayed_work(&xtxhdcp->hdcp_task_monitor, 0); + + return 0; + } + } + if (xtxhdcp->hdcp1xenable) { + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + xlnx_hdcp1x_tx_timer_init(xhdcp1x, xtxhdcp->xhdcptmr); + xlnx_hdcp_tmrcntr_set_handler(xtxhdcp->xhdcptmr, + xlnx_hcdp_tx_timer_callback, + (void *)xtxhdcp); + xhdcp1x->lane_count = lanecount; + xlnx_hdcptx_read_ds_sink_capability(xtxhdcp); + if (xtxhdcp->hdcp_protocol == XHDCPTX_HDCP_1X) { + xhdcp1x->lane_count = lanecount; + xlnx_start_hdcp1x_engine(xhdcp1x); + schedule_delayed_work(&xtxhdcp->hdcp_task_monitor, 0); + + return 0; + } + } else { + dev_err(xtxhdcp->dev, "Downstream is not a HDCP complaint Device\n"); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(xlnx_start_hdcp_engine); + +int xlnx_hdcp_tx_set_callback(void *ref, + enum xlnx_hdcptx_callback_type callback_type, + void *callbackfunc) +{ + int ret = 0; + struct xlnx_hdcptx *xtxhdcp = (struct xlnx_hdcptx *)ref; + + if (xtxhdcp->hdcp2xenable) { + struct xlnx_hdcp2x_config *xhdcp2x = xtxhdcp->xhdcp2x; + + switch (callback_type) { + case XHDCPTX_HANDLER_AUX_READ: + xhdcp2x->handlers.rd_handler = callbackfunc; + break; + case XHDCPTX_HANDLER_AUX_WRITE: + xhdcp2x->handlers.wr_handler = callbackfunc; + break; + case XHDCPTX_HANDLER_HDCP_STATUS: + xhdcp2x->handlers.notify_handler = callbackfunc; + break; + default: + dev_err(xtxhdcp->dev, "Invalid handler type\n"); + ret = -EINVAL; + break; + } + } + if (xtxhdcp->hdcp1xenable) { + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + switch (callback_type) { + case XHDCPTX_HANDLER_AUX_READ: + xhdcp1x->handlers.rd_handler = callbackfunc; + break; + case XHDCPTX_HANDLER_AUX_WRITE: + xhdcp1x->handlers.wr_handler = callbackfunc; + break; + case XHDCPTX_HANDLER_HDCP_STATUS: + xhdcp1x->handlers.notify_handler = callbackfunc; + break; + default: + dev_err(xtxhdcp->dev, "Invalid handler type\n"); + ret = -EINVAL; + break; + } + } + return ret; +} +EXPORT_SYMBOL_GPL(xlnx_hdcp_tx_set_callback); + +void xlnx_hdcp1x_interrupt_handler(struct xlnx_hdcptx *xtxhdcp) +{ + if (xtxhdcp->hdcp1xenable) { + u32 interrupts; + struct xlnx_hdcp1x_config *xhdcp1x = xtxhdcp->xhdcp1x; + + if (xhdcp1x_cipher_get_interrupts(xhdcp1x->cipher, &interrupts)) + return; + + xlnx_hdcp1x_tx_process_ri_event(xhdcp1x); + } +} +EXPORT_SYMBOL_GPL(xlnx_hdcp1x_interrupt_handler); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_tx.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/hdcp/xlnx_hdcp_tx.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * HDCP Interface driver + * + * Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved. + * + * Author: Lakshmi Prasanna Eachuri + */ + +#ifndef _XLNX_HDCP_TX_H_ +#define _XLNX_HDCP_TX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "xlnx_hdcp2x_tx.h" + +#define XHDCP_KEY_WRITE_PERMISSION 0220 + +enum xlnx_hdcptx_callback_type { + XHDCPTX_HANDLER_AUX_READ = 0, + XHDCPTX_HANDLER_AUX_WRITE = 1, + XHDCPTX_HANDLER_HDCP_STATUS = 2, + XHDCPTX_HANDLER_INVALID = 3 +}; + +enum xlnx_hdcptx_protocol_type { + XHDCPTX_HDCP_NONE = 0, + XHDCPTX_HDCP_1X = 1, + XHDCPTX_HDCP_2X = 2, + XHDCPTX_HDCP_BOTH = 3 +}; + +enum xlnx_hdcptx_authstatus { + XHDCPTX_INCOMPATIBLE_RX = 0, + XHDCPTX_AUTHENTICATION_BUSY = 1, + XHDCPTX_AUTHENTICATED = 2, + XHDCPTX_UNAUTHENTICATED = 3, + XHDCPTX_REAUTHENTICATE_REQUESTED = 4, + XHDCPTX_DEVICE_IS_REVOKED = 5, + XHDCPTX_NO_SRM_LOADED = 6 +}; + +/** + * struct xlnx_hdcptx - This structure contains hardware subcore configuration + * information about HDCP protocol hardware engine. + * @dev: platform device + * @xhdcp2x: HDCP2X configuration structure + * @xhdcp1x: HDCP1X configuration structure + * @xhdcptmr: Axi timer for HDCP module + * @hdcptx_mutex: Mutex for HDCP state machine + * @hdcp_task_monitor: Work function for HDCP + * @hdcp_protocol: Protocol type, HDCP1x, HDCP2X or supports both + * @auth_status: Authentication status + * @hdcp2xenable: HDCP2X protocol is enabled + * @hdcp1xenable: HDCP1X protocol is enabled + * @is_enckey_available: Availability of encryption keys + * @is_hdcp_initialized: Flag to check whether HDCP driver is initialized or not + */ +struct xlnx_hdcptx { + struct device *dev; + struct xlnx_hdcp2x_config *xhdcp2x; + struct xlnx_hdcp1x_config *xhdcp1x; + struct xlnx_hdcp_timer_config *xhdcptmr; + struct mutex hdcptx_mutex; /* Mutex for HDCP state machine */ + struct delayed_work hdcp_task_monitor; + enum xlnx_hdcptx_protocol_type hdcp_protocol; + enum xlnx_hdcptx_authstatus auth_status; + bool hdcp2xenable; + bool hdcp1xenable; + bool is_enckey_available; + bool is_hdcp_initialized; +}; + +int xlnx_hdcp_tx_reset(struct xlnx_hdcptx *xtxhdcp); +int xlnx_start_hdcp_engine(struct xlnx_hdcptx *xtxhdcp, u8 lanecount); +int xlnx_hdcp_tx_exit(struct xlnx_hdcptx *xtxhdcp); +int xlnx_hdcp_tx_set_callback(void *ref, + enum xlnx_hdcptx_callback_type callback_type, + void *callbackfunc); +int xlnx_hdcp_tx_set_keys(struct xlnx_hdcptx *xtxhdcp, const u8 *data); + +void xlnx_hdcp1x_interrupt_handler(struct xlnx_hdcptx *xtxhdcp); +void *xlnx_hdcp_tx_init(struct device *dev, void *protocol_ref, + struct xlnx_hdcptx *xtxhdcp, void __iomem *hdcp_base_address, + u8 is_repeater, enum xlnx_hdcptx_protocol_type, u8 lane_count, + int hw_protocol, struct regmap *key_base_address); +void *xlnx_hdcp_timer_init(struct device *dev, void __iomem *interface_base); +void xlnx_hdcp_tx_process_cp_irq(struct xlnx_hdcptx *xhdcptx); +void xlnx_hdcp_tx_timer_exit(struct xlnx_hdcptx *xtxhdcp); +void xlnx_hdcptx_read_ds_sink_capability(struct xlnx_hdcptx *xtxhdcp); + +#endif --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_bridge.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_bridge.c @@ -0,0 +1,575 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx DRM bridge driver + * + * Copyright (C) 2017 Xilinx, Inc. + * + * Author: Hyun Woo Kwon + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include "xlnx_bridge.h" +#include "xlnx_drv.h" + +/* + * Overview + * -------- + * + * Similar to drm bridge, but this can be used by any DRM driver. There + * is no limitation to be used by non DRM drivers as well. No complex topology + * is modeled, thus it's assumed that the Xilinx bridge device is directly + * attached to client. The client should call Xilinx bridge functions explicitly + * where it's needed, as opposed to drm bridge functions which are called + * implicitly by DRM core. + * One Xlnx bridge can be owned by one driver at a time. + */ + +/** + * struct xlnx_bridge_helper - Xilinx bridge helper + * @xlnx_bridges: list of Xilinx bridges + * @lock: lock to protect @xlnx_crtcs + * @refcnt: reference count + * @error: flag if in error state + */ +struct xlnx_bridge_helper { + struct list_head xlnx_bridges; + struct mutex lock; /* lock for @xlnx_bridges */ + unsigned int refcnt; + bool error; +}; + +static struct xlnx_bridge_helper helper; + +struct videomode; +/* + * Client functions + */ + +/** + * xlnx_bridge_enable - Enable the bridge + * @bridge: bridge to enable + * + * Enable bridge. + * + * Return: 0 on success. -ENOENT if no callback, -EFAULT in error state, + * or return code from callback. + */ +int xlnx_bridge_enable(struct xlnx_bridge *bridge) +{ + if (!bridge) + return 0; + + if (helper.error) + return -EFAULT; + + if (bridge->enable) + return bridge->enable(bridge); + + return -ENOENT; +} +EXPORT_SYMBOL(xlnx_bridge_enable); + +/** + * xlnx_bridge_disable - Disable the bridge + * @bridge: bridge to disable + * + * Disable bridge. + */ +void xlnx_bridge_disable(struct xlnx_bridge *bridge) +{ + if (!bridge) + return; + + if (helper.error) + return; + + if (bridge->disable) + bridge->disable(bridge); +} +EXPORT_SYMBOL(xlnx_bridge_disable); + +/** + * xlnx_bridge_set_input - Set the input of @bridge + * @bridge: bridge to set + * @width: width + * @height: height + * @bus_fmt: bus format (ex, MEDIA_BUS_FMT_*); + * + * Set the bridge input with height / width / format. + * + * Return: 0 on success. -ENOENT if no callback, -EFAULT if in error state, + * or return code from callback. + */ +int xlnx_bridge_set_input(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt) +{ + if (!bridge) + return 0; + + if (helper.error) + return -EFAULT; + + if (bridge->set_input) + return bridge->set_input(bridge, width, height, bus_fmt); + + return -ENOENT; +} +EXPORT_SYMBOL(xlnx_bridge_set_input); + +/** + * xlnx_bridge_get_input_fmts - Get the supported input formats + * @bridge: bridge to set + * @fmts: pointer to formats + * @count: pointer to format count + * + * Get the list of supported input bus formats. + * + * Return: 0 on success. -ENOENT if no callback, -EFAULT if in error state, + * or return code from callback. + */ +int xlnx_bridge_get_input_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count) +{ + if (!bridge) + return 0; + + if (helper.error) + return -EFAULT; + + if (bridge->get_input_fmts) + return bridge->get_input_fmts(bridge, fmts, count); + + return -ENOENT; +} +EXPORT_SYMBOL(xlnx_bridge_get_input_fmts); + +/** + * xlnx_bridge_set_output - Set the output of @bridge + * @bridge: bridge to set + * @width: width + * @height: height + * @bus_fmt: bus format (ex, MEDIA_BUS_FMT_*); + * + * Set the bridge output with height / width / format. + * + * Return: 0 on success. -ENOENT if no callback, -EFAULT if in error state, + * or return code from callback. + */ +int xlnx_bridge_set_output(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt) +{ + if (!bridge) + return 0; + + if (helper.error) + return -EFAULT; + + if (bridge->set_output) + return bridge->set_output(bridge, width, height, bus_fmt); + + return -ENOENT; +} +EXPORT_SYMBOL(xlnx_bridge_set_output); + +/** + * xlnx_bridge_get_output_fmts - Get the supported output formats + * @bridge: bridge to set + * @fmts: pointer to formats + * @count: pointer to format count + * + * Get the list of supported output bus formats. + * + * Return: 0 on success. -ENOENT if no callback, -EFAULT if in error state, + * or return code from callback. + */ +int xlnx_bridge_get_output_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count) +{ + if (!bridge) + return 0; + + if (helper.error) + return -EFAULT; + + if (bridge->get_output_fmts) + return bridge->get_output_fmts(bridge, fmts, count); + + return -ENOENT; +} +EXPORT_SYMBOL(xlnx_bridge_get_output_fmts); + +/** + * xlnx_bridge_set_timing - Set the video timing + * @bridge: bridge to set + * @vm: Videomode + * + * Set the video mode so that timing can be generated using this + * by the video timing controller. + * + * Return: 0 on success. -ENOENT if no callback, -EFAULT if in error state, + * or return code from callback. + */ +int xlnx_bridge_set_timing(struct xlnx_bridge *bridge, struct videomode *vm) +{ + if (!bridge) + return 0; + + if (helper.error) + return -EFAULT; + + if (bridge->set_timing) { + bridge->set_timing(bridge, vm); + return 0; + } + + return -ENOENT; +} +EXPORT_SYMBOL(xlnx_bridge_set_timing); + +/** + * of_xlnx_bridge_get - Get the corresponding Xlnx bridge instance + * @bridge_np: The device node of the bridge device + * + * The function walks through the Xlnx bridge list of @drm, and return + * if any registered bridge matches the device node. The returned + * bridge will not be accesible by others. + * + * Return: the matching Xlnx bridge instance, or NULL + */ +struct xlnx_bridge *of_xlnx_bridge_get(struct device_node *bridge_np) +{ + struct xlnx_bridge *found = NULL; + struct xlnx_bridge *bridge; + + if (helper.error) + return NULL; + + mutex_lock(&helper.lock); + list_for_each_entry(bridge, &helper.xlnx_bridges, list) { + if (bridge->of_node == bridge_np && !bridge->owned) { + found = bridge; + bridge->owned = true; + break; + } + } + mutex_unlock(&helper.lock); + + return found; +} +EXPORT_SYMBOL_GPL(of_xlnx_bridge_get); + +/** + * of_xlnx_bridge_put - Put the Xlnx bridge instance + * @bridge: Xlnx bridge instance to release + * + * Return the @bridge. After this, the bridge will be available for + * other drivers to use. + */ +void of_xlnx_bridge_put(struct xlnx_bridge *bridge) +{ + if (WARN_ON(helper.error)) + return; + + mutex_lock(&helper.lock); + WARN_ON(!bridge->owned); + bridge->owned = false; + mutex_unlock(&helper.lock); +} +EXPORT_SYMBOL_GPL(of_xlnx_bridge_put); + +#ifdef CONFIG_DRM_XLNX_BRIDGE_DEBUG_FS + +#include + +struct xlnx_bridge_debugfs_dir { + struct dentry *dir; + int ref_cnt; +}; + +static struct xlnx_bridge_debugfs_dir *dir; + +struct xlnx_bridge_debugfs_file { + struct dentry *file; + const char *status; +}; + +#define XLNX_BRIDGE_DEBUGFS_MAX_BYTES 16 + +static ssize_t xlnx_bridge_debugfs_read(struct file *f, char __user *buf, + size_t size, loff_t *pos) +{ + struct xlnx_bridge *bridge = f->f_inode->i_private; + int ret, count = 0; + + if (size <= 0) + return -EINVAL; + + if (*pos != 0) + return 0; + + if (bridge->debugfs_file->status) { + count = min(size, strlen(bridge->debugfs_file->status)); + ret = copy_to_user(buf, bridge->debugfs_file->status, count); + if (ret) + count = -EFAULT; + } + + return count; +} + +static ssize_t xlnx_bridge_debugfs_write(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + struct xlnx_bridge *bridge = f->f_inode->i_private; + + if (*pos != 0 || size <= 0) + return -EINVAL; + + if (!strncmp(buf, "enable", 5)) { + xlnx_bridge_enable(bridge); + } else if (!strncmp(buf, "disable", 6)) { + xlnx_bridge_disable(bridge); + } else if (!strncmp(buf, "set_input", 3)) { + char *cmd, **tmp; + char *w, *h, *bus_fmt; + u32 width = 0, height = 0, fmt = 0; + int ret; + + cmd = kzalloc(size, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + ret = strncpy_from_user(cmd, buf, size); + if (ret < 0) { + pr_err("%s %d failed to copy the command %s\n", + __func__, __LINE__, buf); + kfree(cmd); + return ret; + } + + tmp = &cmd; + strsep(tmp, " "); + w = strsep(tmp, " "); + h = strsep(tmp, " "); + bus_fmt = strsep(tmp, " "); + if (w && h && bus_fmt) { + ret = kstrtouint(w, 0, &width); + ret |= kstrtouint(h, 0, &height); + ret |= kstrtouint(bus_fmt, 0, &fmt); + } + + kfree(cmd); + if (ret) { + pr_err("%s %d invalid command: %s\n", + __func__, __LINE__, buf); + return -EINVAL; + } + xlnx_bridge_set_input(bridge, width, height, fmt); + } + + return size; +} + +static const struct file_operations xlnx_bridge_debugfs_fops = { + .owner = THIS_MODULE, + .read = xlnx_bridge_debugfs_read, + .write = xlnx_bridge_debugfs_write, +}; + +static int xlnx_bridge_debugfs_register(struct xlnx_bridge *bridge) +{ + struct xlnx_bridge_debugfs_file *file; + char file_name[32]; + + file = kzalloc(sizeof(*file), GFP_KERNEL); + if (!file) + return -ENOMEM; + + if (bridge->extra_name) + snprintf(file_name, sizeof(file_name), "xlnx_bridge-%s%s", + bridge->of_node->name, bridge->extra_name); + else + snprintf(file_name, sizeof(file_name), "xlnx_bridge-%s", + bridge->of_node->name); + file->file = debugfs_create_file(file_name, 0444, dir->dir, bridge, + &xlnx_bridge_debugfs_fops); + bridge->debugfs_file = file; + + return 0; +} + +static void xlnx_bridge_debugfs_unregister(struct xlnx_bridge *bridge) +{ + if (!bridge->debugfs_file) { + pr_err("bridge %s debugfs file is NULL\n", bridge->of_node->name); + return; + } + debugfs_remove(bridge->debugfs_file->file); + kfree(bridge->debugfs_file); +} + +static int xlnx_bridge_debugfs_init(void) +{ + if (dir) { + dir->ref_cnt++; + return 0; + } + + dir = kzalloc(sizeof(*dir), GFP_KERNEL); + if (!dir) + return -ENOMEM; + + dir->dir = debugfs_create_dir("xlnx-bridge", NULL); + if (!dir->dir) + return -ENODEV; + dir->ref_cnt++; + + return 0; +} + +static void xlnx_bridge_debugfs_fini(void) +{ + if (--dir->ref_cnt) + return; + + debugfs_remove_recursive(dir->dir); + dir = NULL; +} + +#else + +static int xlnx_bridge_debugfs_register(struct xlnx_bridge *bridge) +{ + return 0; +} + +static void xlnx_bridge_debugfs_unregister(struct xlnx_bridge *bridge) +{ +} + +static int xlnx_bridge_debugfs_init(void) +{ + return 0; +} + +static void xlnx_bridge_debugfs_fini(void) +{ +} + +#endif + +/* + * Provider functions + */ + +/** + * xlnx_bridge_register - Register the bridge instance + * @bridge: Xlnx bridge instance to register + * + * Register @bridge to be available for clients. + * + * Return: 0 on success. -EPROBE_DEFER if helper is not initialized, or + * -EFAULT if in error state. + */ +int xlnx_bridge_register(struct xlnx_bridge *bridge) +{ + if (!helper.refcnt) + return -EPROBE_DEFER; + + if (helper.error) + return -EFAULT; + + mutex_lock(&helper.lock); + WARN_ON(!bridge->of_node); + bridge->owned = false; + xlnx_bridge_debugfs_register(bridge); + list_add_tail(&bridge->list, &helper.xlnx_bridges); + mutex_unlock(&helper.lock); + + return 0; +} +EXPORT_SYMBOL_GPL(xlnx_bridge_register); + +/** + * xlnx_bridge_unregister - Unregister the bridge instance + * @bridge: Xlnx bridge instance to unregister + * + * Unregister @bridge. The bridge shouldn't be owned by any client + * at this point. + */ +void xlnx_bridge_unregister(struct xlnx_bridge *bridge) +{ + if (helper.error) + return; + + mutex_lock(&helper.lock); + pr_warn("unregister bridge %s which is owned by other component\n", + bridge->of_node->name); + xlnx_bridge_debugfs_unregister(bridge); + list_del(&bridge->list); + mutex_unlock(&helper.lock); +} +EXPORT_SYMBOL_GPL(xlnx_bridge_unregister); + +/* + * Internal functions: used by Xlnx DRM + */ + +/** + * xlnx_bridge_helper_init - Initialize the bridge helper + * @void: No arg + * + * Initialize the bridge helper or increment the reference count + * if already initialized. + * + * Return: 0 on success, or -EFAULT if in error state. + */ +int xlnx_bridge_helper_init(void) +{ + if (helper.refcnt++ > 0) { + if (helper.error) + return -EFAULT; + return 0; + } + + INIT_LIST_HEAD(&helper.xlnx_bridges); + mutex_init(&helper.lock); + helper.error = false; + + if (xlnx_bridge_debugfs_init()) + pr_err("failed to init xlnx bridge debugfs\n"); + + return 0; +} + +/** + * xlnx_bridge_helper_fini - Release the bridge helper + * + * Clean up or decrement the reference of the bridge helper. + */ +void xlnx_bridge_helper_fini(void) +{ + if (--helper.refcnt > 0) + return; + + xlnx_bridge_debugfs_fini(); + + if (WARN_ON(!list_empty(&helper.xlnx_bridges))) { + helper.error = true; + pr_err("any further xlnx bridge call will fail\n"); + } + + mutex_destroy(&helper.lock); +} --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_bridge.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_bridge.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx DRM bridge header + * + * Copyright (C) 2017 Xilinx, Inc. + * + * Author: Hyun Woo Kwon + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _XLNX_BRIDGE_H_ +#define _XLNX_BRIDGE_H_ + +struct videomode; + +struct xlnx_bridge_debugfs_file; + +/** + * struct xlnx_bridge - Xilinx bridge device + * @list: list node for Xilinx bridge device list + * @of_node: OF node for the bridge + * @owned: flag if the bridge is owned + * @enable: callback to enable the bridge + * @disable: callback to disable the bridge + * @set_input: callback to set the input + * @get_input_fmts: callback to get supported input formats. + * @set_output: callback to set the output + * @get_output_fmts: callback to get supported output formats. + * @set_timing: callback to set timing in connected video timing controller. + * @debugfs_file: for debugfs support + * @extra_name: name to distinguish the bridges which share the same of_node + */ +struct xlnx_bridge { + struct list_head list; + struct device_node *of_node; + bool owned; + int (*enable)(struct xlnx_bridge *bridge); + void (*disable)(struct xlnx_bridge *bridge); + int (*set_input)(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt); + int (*get_input_fmts)(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count); + int (*set_output)(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt); + int (*get_output_fmts)(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count); + int (*set_timing)(struct xlnx_bridge *bridge, struct videomode *vm); + struct xlnx_bridge_debugfs_file *debugfs_file; + char *extra_name; +}; + +#if IS_ENABLED(CONFIG_DRM_XLNX_BRIDGE) +/* + * Helper functions: used within Xlnx DRM + */ + +struct xlnx_bridge_helper; + +int xlnx_bridge_helper_init(void); +void xlnx_bridge_helper_fini(void); + +/* + * Helper functions: used by client driver + */ + +int xlnx_bridge_enable(struct xlnx_bridge *bridge); +void xlnx_bridge_disable(struct xlnx_bridge *bridge); +int xlnx_bridge_set_input(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt); +int xlnx_bridge_get_input_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count); +int xlnx_bridge_set_output(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt); +int xlnx_bridge_get_output_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count); +int xlnx_bridge_set_timing(struct xlnx_bridge *bridge, struct videomode *vm); +struct xlnx_bridge *of_xlnx_bridge_get(struct device_node *bridge_np); +void of_xlnx_bridge_put(struct xlnx_bridge *bridge); + +/* + * Bridge registration: used by bridge driver + */ + +int xlnx_bridge_register(struct xlnx_bridge *bridge); +void xlnx_bridge_unregister(struct xlnx_bridge *bridge); + +#else /* CONFIG_DRM_XLNX_BRIDGE */ + +struct xlnx_bridge_helper; + +static inline int xlnx_bridge_helper_init(void) +{ + return 0; +} + +static inline void xlnx_bridge_helper_fini(void) +{ +} + +static inline int xlnx_bridge_enable(struct xlnx_bridge *bridge) +{ + if (bridge) + return -ENODEV; + return 0; +} + +static inline void xlnx_bridge_disable(struct xlnx_bridge *bridge) +{ +} + +static inline int xlnx_bridge_set_input(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt) +{ + if (bridge) + return -ENODEV; + return 0; +} + +static inline int xlnx_bridge_get_input_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count) +{ + if (bridge) + return -ENODEV; + return 0; +} + +static inline int xlnx_bridge_set_output(struct xlnx_bridge *bridge, + u32 width, u32 height, u32 bus_fmt) +{ + if (bridge) + return -ENODEV; + return 0; +} + +static inline int xlnx_bridge_get_output_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count) +{ + if (bridge) + return -ENODEV; + return 0; +} + +static inline int xlnx_bridge_set_timing(struct xlnx_bridge *bridge, + struct videomode *vm) +{ + if (bridge) + return -ENODEV; + return 0; +} + +static inline struct xlnx_bridge * +of_xlnx_bridge_get(struct device_node *bridge_np) +{ + return NULL; +} + +static inline void of_xlnx_bridge_put(struct xlnx_bridge *bridge) +{ +} + +static inline int xlnx_bridge_register(struct xlnx_bridge *bridge) +{ + return 0; +} + +static inline void xlnx_bridge_unregister(struct xlnx_bridge *bridge) +{ +} + +#endif /* CONFIG_DRM_XLNX_BRIDGE */ + +#endif /* _XLNX_BRIDGE_H_ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_crtc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_crtc.c @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx DRM crtc driver + * + * Copyright (C) 2017 - 2018 Xilinx, Inc. + * + * Author: Hyun Woo Kwon + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include +#include + +#include "xlnx_crtc.h" +#include "xlnx_drv.h" + +/* + * Overview + * -------- + * + * The Xilinx CRTC layer is to enable the custom interface to CRTC drivers. + * The interface is used by Xilinx DRM driver where it needs CRTC + * functionailty. CRTC drivers should attach the desired callbacks + * to struct xlnx_crtc and register the xlnx_crtc with correcsponding + * drm_device. It's highly recommended CRTC drivers register all callbacks + * even though many of them are optional. + * The CRTC helper simply walks through the registered CRTC device, + * and call the callbacks. + */ + +/** + * struct xlnx_crtc_helper - Xilinx CRTC helper + * @xlnx_crtcs: list of Xilinx CRTC devices + * @lock: lock to protect @xlnx_crtcs + * @drm: back pointer to DRM core + */ +struct xlnx_crtc_helper { + struct list_head xlnx_crtcs; + struct mutex lock; /* lock for @xlnx_crtcs */ + struct drm_device *drm; +}; + +#define XLNX_CRTC_MAX_HEIGHT_WIDTH INT_MAX + +unsigned int xlnx_crtc_helper_get_align(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + unsigned int align = 1, tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_align) { + tmp = crtc->get_align(crtc); + align = ALIGN(align, tmp); + } + } + + return align; +} + +u64 xlnx_crtc_helper_get_dma_mask(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + u64 mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8), tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_dma_mask) { + tmp = crtc->get_dma_mask(crtc); + mask = min(mask, tmp); + } + } + + return mask; +} + +int xlnx_crtc_helper_get_max_width(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + int width = XLNX_CRTC_MAX_HEIGHT_WIDTH, tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_max_width) { + tmp = crtc->get_max_width(crtc); + width = min(width, tmp); + } + } + + return width; +} + +int xlnx_crtc_helper_get_max_height(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + int height = XLNX_CRTC_MAX_HEIGHT_WIDTH, tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_max_height) { + tmp = crtc->get_max_height(crtc); + height = min(height, tmp); + } + } + + return height; +} + +uint32_t xlnx_crtc_helper_get_format(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + u32 format = 0, tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_format) { + tmp = crtc->get_format(crtc); + if (format && format != tmp) + return 0; + format = tmp; + } + } + + return format; +} + +u32 xlnx_crtc_helper_get_cursor_width(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + u32 width = XLNX_CRTC_MAX_HEIGHT_WIDTH, tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_cursor_width) { + tmp = crtc->get_cursor_width(crtc); + width = min(width, tmp); + } + } + + return width; +} + +u32 xlnx_crtc_helper_get_cursor_height(struct xlnx_crtc_helper *helper) +{ + struct xlnx_crtc *crtc; + u32 height = XLNX_CRTC_MAX_HEIGHT_WIDTH, tmp; + + list_for_each_entry(crtc, &helper->xlnx_crtcs, list) { + if (crtc->get_cursor_height) { + tmp = crtc->get_cursor_height(crtc); + height = min(height, tmp); + } + } + + return height; +} +struct xlnx_crtc_helper *xlnx_crtc_helper_init(struct drm_device *drm) +{ + struct xlnx_crtc_helper *helper; + + helper = devm_kzalloc(drm->dev, sizeof(*helper), GFP_KERNEL); + if (!helper) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&helper->xlnx_crtcs); + mutex_init(&helper->lock); + helper->drm = drm; + + return helper; +} + +void xlnx_crtc_helper_fini(struct drm_device *drm, + struct xlnx_crtc_helper *helper) +{ + if (WARN_ON(helper->drm != drm)) + return; + + if (WARN_ON(!list_empty(&helper->xlnx_crtcs))) + return; + + mutex_destroy(&helper->lock); + devm_kfree(drm->dev, helper); +} + +void xlnx_crtc_register(struct drm_device *drm, struct xlnx_crtc *crtc) +{ + struct xlnx_crtc_helper *helper = xlnx_get_crtc_helper(drm); + + mutex_lock(&helper->lock); + list_add_tail(&crtc->list, &helper->xlnx_crtcs); + mutex_unlock(&helper->lock); +} +EXPORT_SYMBOL_GPL(xlnx_crtc_register); + +void xlnx_crtc_unregister(struct drm_device *drm, struct xlnx_crtc *crtc) +{ + struct xlnx_crtc_helper *helper = xlnx_get_crtc_helper(drm); + + mutex_lock(&helper->lock); + list_del(&crtc->list); + mutex_unlock(&helper->lock); +} +EXPORT_SYMBOL_GPL(xlnx_crtc_unregister); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_crtc.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_crtc.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx DRM crtc header + * + * Copyright (C) 2017 - 2018 Xilinx, Inc. + * + * Author: Hyun Woo Kwon + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _XLNX_CRTC_H_ +#define _XLNX_CRTC_H_ + +/** + * struct xlnx_crtc - Xilinx CRTC device + * @crtc: DRM CRTC device + * @list: list node for Xilinx CRTC device list + * @get_align: Get the alignment requirement of CRTC device + * @get_dma_mask: Get the dma mask of CRTC device + * @get_max_width: Get the maximum supported width + * @get_max_height: Get the maximum supported height + * @get_format: Get the current format of CRTC device + * @get_cursor_width: Get the cursor width + * @get_cursor_height: Get the cursor height + */ +struct xlnx_crtc { + struct drm_crtc crtc; + struct list_head list; + unsigned int (*get_align)(struct xlnx_crtc *crtc); + u64 (*get_dma_mask)(struct xlnx_crtc *crtc); + int (*get_max_width)(struct xlnx_crtc *crtc); + int (*get_max_height)(struct xlnx_crtc *crtc); + uint32_t (*get_format)(struct xlnx_crtc *crtc); + uint32_t (*get_cursor_width)(struct xlnx_crtc *crtc); + uint32_t (*get_cursor_height)(struct xlnx_crtc *crtc); +}; + +/* + * Helper functions: used within Xlnx DRM + */ + +struct xlnx_crtc_helper; + +unsigned int xlnx_crtc_helper_get_align(struct xlnx_crtc_helper *helper); +u64 xlnx_crtc_helper_get_dma_mask(struct xlnx_crtc_helper *helper); +int xlnx_crtc_helper_get_max_width(struct xlnx_crtc_helper *helper); +int xlnx_crtc_helper_get_max_height(struct xlnx_crtc_helper *helper); +uint32_t xlnx_crtc_helper_get_format(struct xlnx_crtc_helper *helper); +u32 xlnx_crtc_helper_get_cursor_width(struct xlnx_crtc_helper *helper); +u32 xlnx_crtc_helper_get_cursor_height(struct xlnx_crtc_helper *helper); + +struct xlnx_crtc_helper *xlnx_crtc_helper_init(struct drm_device *drm); +void xlnx_crtc_helper_fini(struct drm_device *drm, + struct xlnx_crtc_helper *helper); + +/* + * CRTC registration: used by other sub-driver modules + */ + +static inline struct xlnx_crtc *to_xlnx_crtc(struct drm_crtc *crtc) +{ + return container_of(crtc, struct xlnx_crtc, crtc); +} + +void xlnx_crtc_register(struct drm_device *drm, struct xlnx_crtc *crtc); +void xlnx_crtc_unregister(struct drm_device *drm, struct xlnx_crtc *crtc); + +#endif /* _XLNX_CRTC_H_ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_csc.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_csc.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * VPSS CSC DRM bridge driver + * + * Copyright (C) 2017-2018 Xilinx, Inc. + * + * Author: Venkateshwar rao G + */ + +/* + * Overview: + * This experimentatl driver works as a bridge driver and + * reused the code from V4L2. + * TODO: + * Need to implement in a modular approach to share driver code between + * V4L2 and DRM frameworks. + * Should be integrated with plane + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xlnx_bridge.h" + +/* Register offset */ +#define XV_CSC_AP_CTRL (0x000) +#define XV_CSC_INVIDEOFORMAT (0x010) +#define XV_CSC_OUTVIDEOFORMAT (0x018) +#define XV_CSC_WIDTH (0x020) +#define XV_CSC_HEIGHT (0x028) +#define XV_CSC_K11 (0x050) +#define XV_CSC_K12 (0x058) +#define XV_CSC_K13 (0x060) +#define XV_CSC_K21 (0x068) +#define XV_CSC_K22 (0x070) +#define XV_CSC_K23 (0x078) +#define XV_CSC_K31 (0x080) +#define XV_CSC_K32 (0x088) +#define XV_CSC_K33 (0x090) +#define XV_CSC_ROFFSET (0x098) +#define XV_CSC_GOFFSET (0x0a0) +#define XV_CSC_BOFFSET (0x0a8) +#define XV_CSC_CLAMPMIN (0x0b0) +#define XV_CSC_CLIPMAX (0x0b8) +#define XV_CSC_SCALE_FACTOR (4096) +#define XV_CSC_DIVISOR (10000) +/* Streaming Macros */ +#define XCSC_CLAMP_MIN_ZERO (0) +#define XCSC_AP_START BIT(0) +#define XCSC_AP_AUTO_RESTART BIT(7) +#define XCSC_STREAM_ON (XCSC_AP_START | XCSC_AP_AUTO_RESTART) +#define XCSC_STREAM_OFF (0) +/* GPIO Reset Assert/De-assert */ +#define XCSC_RESET_ASSERT (1) +#define XCSC_RESET_DEASSERT (0) + +#define XCSC_MIN_WIDTH (64) +#define XCSC_MAX_WIDTH (8192) +#define XCSC_MIN_HEIGHT (64) +#define XCSC_MAX_HEIGHT (4320) + +static const u32 xilinx_csc_video_fmts[] = { + MEDIA_BUS_FMT_RGB888_1X24, + MEDIA_BUS_FMT_VUY8_1X24, + MEDIA_BUS_FMT_UYVY8_1X16, + MEDIA_BUS_FMT_VYYUYY8_1X24, +}; + +/* vpss_csc_color_fmt - Color format type */ +enum vpss_csc_color_fmt { + XVIDC_CSF_RGB = 0, + XVIDC_CSF_YCRCB_444, + XVIDC_CSF_YCRCB_422, + XVIDC_CSF_YCRCB_420, +}; + +/** + * struct xilinx_csc - Core configuration of csc device structure + * @base: pointer to register base address + * @dev: device structure + * @bridge: xilinx bridge + * @cft_in: input color format + * @cft_out: output color format + * @color_depth: color depth + * @k_hw: array of hardware values + * @clip_max: clipping maximum value + * @width: width of the video + * @height: height of video + * @max_width: maximum number of pixels in a line + * @max_height: maximum number of lines per frame + * @rst_gpio: Handle to GPIO specifier to assert/de-assert the reset line + * @aclk: IP clock struct + */ +struct xilinx_csc { + void __iomem *base; + struct device *dev; + struct xlnx_bridge bridge; + enum vpss_csc_color_fmt cft_in; + enum vpss_csc_color_fmt cft_out; + u32 color_depth; + s32 k_hw[3][4]; + s32 clip_max; + u32 width; + u32 height; + u32 max_width; + u32 max_height; + struct gpio_desc *rst_gpio; + struct clk *aclk; +}; + +static inline void xilinx_csc_write(void __iomem *base, u32 offset, u32 val) +{ + writel(val, base + offset); +} + +static inline u32 xilinx_csc_read(void __iomem *base, u32 offset) +{ + return readl(base + offset); +} + +/** + * bridge_to_layer - Gets the parent structure + * @bridge: pointer to the member. + * + * Return: parent structure pointer + */ +static inline struct xilinx_csc *bridge_to_layer(struct xlnx_bridge *bridge) +{ + return container_of(bridge, struct xilinx_csc, bridge); +} + +static void xilinx_csc_write_rgb_3x3(struct xilinx_csc *csc) +{ + xilinx_csc_write(csc->base, XV_CSC_K11, csc->k_hw[0][0]); + xilinx_csc_write(csc->base, XV_CSC_K12, csc->k_hw[0][1]); + xilinx_csc_write(csc->base, XV_CSC_K13, csc->k_hw[0][2]); + xilinx_csc_write(csc->base, XV_CSC_K21, csc->k_hw[1][0]); + xilinx_csc_write(csc->base, XV_CSC_K22, csc->k_hw[1][1]); + xilinx_csc_write(csc->base, XV_CSC_K23, csc->k_hw[1][2]); + xilinx_csc_write(csc->base, XV_CSC_K31, csc->k_hw[2][0]); + xilinx_csc_write(csc->base, XV_CSC_K32, csc->k_hw[2][1]); + xilinx_csc_write(csc->base, XV_CSC_K33, csc->k_hw[2][2]); +} + +static void xilinx_csc_write_rgb_offset(struct xilinx_csc *csc) +{ + xilinx_csc_write(csc->base, XV_CSC_ROFFSET, csc->k_hw[0][3]); + xilinx_csc_write(csc->base, XV_CSC_GOFFSET, csc->k_hw[1][3]); + xilinx_csc_write(csc->base, XV_CSC_BOFFSET, csc->k_hw[2][3]); +} + +static void xilinx_csc_write_coeff(struct xilinx_csc *csc) +{ + xilinx_csc_write_rgb_3x3(csc); + xilinx_csc_write_rgb_offset(csc); +} + +static void xcsc_set_default_state(struct xilinx_csc *csc) +{ + csc->cft_in = XVIDC_CSF_YCRCB_422; + csc->cft_out = XVIDC_CSF_YCRCB_422; + + /* This represents an identity matrix mutliped by 2^12 */ + csc->k_hw[0][0] = XV_CSC_SCALE_FACTOR; + csc->k_hw[0][1] = 0; + csc->k_hw[0][2] = 0; + csc->k_hw[1][0] = 0; + csc->k_hw[1][1] = XV_CSC_SCALE_FACTOR; + csc->k_hw[1][2] = 0; + csc->k_hw[2][0] = 0; + csc->k_hw[2][1] = 0; + csc->k_hw[2][2] = XV_CSC_SCALE_FACTOR; + csc->k_hw[0][3] = 0; + csc->k_hw[1][3] = 0; + csc->k_hw[2][3] = 0; + csc->clip_max = ((1 << csc->color_depth) - 1); + xilinx_csc_write(csc->base, XV_CSC_INVIDEOFORMAT, csc->cft_in); + xilinx_csc_write(csc->base, XV_CSC_OUTVIDEOFORMAT, csc->cft_out); + xilinx_csc_write_coeff(csc); + xilinx_csc_write(csc->base, XV_CSC_CLIPMAX, csc->clip_max); + xilinx_csc_write(csc->base, XV_CSC_CLAMPMIN, XCSC_CLAMP_MIN_ZERO); +} + +static void xcsc_ycrcb_to_rgb(struct xilinx_csc *csc, s32 *clip_max) +{ + u16 bpc_scale = (1 << (csc->color_depth - 8)); + /* + * See http://graficaobscura.com/matrix/index.html for + * how these numbers are derived. The VPSS CSC IP is + * derived from this Matrix style algorithm. And the + * 'magic' numbers here are derived from the algorithm. + * + * XV_CSC_DIVISOR is used to help with floating constants + * while performing multiplicative operations. + * + * Coefficients valid only for BT 709 + */ + csc->k_hw[0][0] = 11644 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[0][1] = 0; + csc->k_hw[0][2] = 17927 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[1][0] = 11644 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[1][1] = -2132 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[1][2] = -5329 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[2][0] = 11644 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[2][1] = 21124 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[2][2] = 0; + csc->k_hw[0][3] = -248 * bpc_scale; + csc->k_hw[1][3] = 77 * bpc_scale; + csc->k_hw[2][3] = -289 * bpc_scale; + *clip_max = ((1 << csc->color_depth) - 1); +} + +static void xcsc_rgb_to_ycrcb(struct xilinx_csc *csc, s32 *clip_max) +{ + u16 bpc_scale = (1 << (csc->color_depth - 8)); + /* + * See http://graficaobscura.com/matrix/index.html for + * how these numbers are derived. The VPSS CSC + * derived from this Matrix style algorithm. And the + * 'magic' numbers here are derived from the algorithm. + * + * XV_CSC_DIVISOR is used to help with floating constants + * while performing multiplicative operations. + * + * Coefficients valid only for BT 709 + */ + csc->k_hw[0][0] = 1826 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[0][1] = 6142 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[0][2] = 620 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[1][0] = -1006 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[1][1] = -3386 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[1][2] = 4392 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[2][0] = 4392 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[2][1] = -3989 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[2][2] = -403 * XV_CSC_SCALE_FACTOR / XV_CSC_DIVISOR; + csc->k_hw[0][3] = 16 * bpc_scale; + csc->k_hw[1][3] = 128 * bpc_scale; + csc->k_hw[2][3] = 128 * bpc_scale; + *clip_max = ((1 << csc->color_depth) - 1); +} + +/** + * xcsc_set_coeff- Sets the coefficients + * @csc: Pointer to csc device structure + * + * This function set the coefficients + * + */ +static void xcsc_set_coeff(struct xilinx_csc *csc) +{ + xilinx_csc_write(csc->base, XV_CSC_INVIDEOFORMAT, csc->cft_in); + xilinx_csc_write(csc->base, XV_CSC_OUTVIDEOFORMAT, csc->cft_out); + xilinx_csc_write_coeff(csc); + xilinx_csc_write(csc->base, XV_CSC_CLIPMAX, csc->clip_max); + xilinx_csc_write(csc->base, XV_CSC_CLAMPMIN, XCSC_CLAMP_MIN_ZERO); +} + +/** + * xilinx_csc_bridge_enable - enabes csc core + * @bridge: bridge instance + * + * This function enables the csc core + * + * Return: 0 on success. + * + */ +static int xilinx_csc_bridge_enable(struct xlnx_bridge *bridge) +{ + struct xilinx_csc *csc = bridge_to_layer(bridge); + + xilinx_csc_write(csc->base, XV_CSC_AP_CTRL, XCSC_STREAM_ON); + + return 0; +} + +/** + * xilinx_csc_bridge_disable - disables csc core + * @bridge: bridge instance + * + * This function disables the csc core + */ +static void xilinx_csc_bridge_disable(struct xlnx_bridge *bridge) +{ + struct xilinx_csc *csc = bridge_to_layer(bridge); + + xilinx_csc_write(csc->base, XV_CSC_AP_CTRL, XCSC_STREAM_OFF); + /* Reset the Global IP Reset through GPIO */ + gpiod_set_value_cansleep(csc->rst_gpio, XCSC_RESET_ASSERT); + gpiod_set_value_cansleep(csc->rst_gpio, XCSC_RESET_DEASSERT); +} + +/** + * xilinx_csc_bridge_set_input - Sets the input parameters of csc + * @bridge: bridge instance + * @width: width of video + * @height: height of video + * @bus_fmt: video bus format + * + * This function sets the input parameters of csc + * Return: 0 on success. -EINVAL for invalid parameters. + */ +static int xilinx_csc_bridge_set_input(struct xlnx_bridge *bridge, u32 width, + u32 height, u32 bus_fmt) +{ + struct xilinx_csc *csc = bridge_to_layer(bridge); + + xcsc_set_default_state(csc); + + if (height > csc->max_height || height < XCSC_MIN_HEIGHT) + return -EINVAL; + + if (width > csc->max_width || width < XCSC_MIN_WIDTH) + return -EINVAL; + + csc->height = height; + csc->width = width; + + switch (bus_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + csc->cft_in = XVIDC_CSF_RGB; + break; + case MEDIA_BUS_FMT_VUY8_1X24: + csc->cft_in = XVIDC_CSF_YCRCB_444; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + csc->cft_in = XVIDC_CSF_YCRCB_422; + break; + case MEDIA_BUS_FMT_VYYUYY8_1X24: + csc->cft_in = XVIDC_CSF_YCRCB_420; + break; + default: + dev_dbg(csc->dev, "unsupported input video format\n"); + return -EINVAL; + } + + xilinx_csc_write(csc->base, XV_CSC_WIDTH, width); + xilinx_csc_write(csc->base, XV_CSC_HEIGHT, height); + + return 0; +} + +/** + * xilinx_csc_bridge_get_input_fmts - input formats supported by csc + * @bridge: bridge instance + * @fmts: Pointer to be updated with formats information + * @count: count of video bus formats + * + * This function provides the input video formats information csc + * Return: 0 on success. + */ +static int xilinx_csc_bridge_get_input_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count) +{ + *fmts = xilinx_csc_video_fmts; + *count = ARRAY_SIZE(xilinx_csc_video_fmts); + + return 0; +} + +/** + * xilinx_csc_bridge_set_output - Sets the output parameters of csc + * @bridge: bridge instance + * @width: width of video + * @height: height of video + * @bus_fmt: video bus format + * + * This function sets the output parameters of csc + * Return: 0 on success. -EINVAL for invalid parameters. + */ +static int xilinx_csc_bridge_set_output(struct xlnx_bridge *bridge, u32 width, + u32 height, u32 bus_fmt) +{ + struct xilinx_csc *csc = bridge_to_layer(bridge); + + if (width != csc->width || height != csc->height) + return -EINVAL; + + switch (bus_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + csc->cft_out = XVIDC_CSF_RGB; + dev_dbg(csc->dev, "Media Format Out : RGB"); + if (csc->cft_in != MEDIA_BUS_FMT_RBG888_1X24) + xcsc_ycrcb_to_rgb(csc, &csc->clip_max); + break; + case MEDIA_BUS_FMT_VUY8_1X24: + csc->cft_out = XVIDC_CSF_YCRCB_444; + dev_dbg(csc->dev, "Media Format Out : YUV 444"); + if (csc->cft_in == MEDIA_BUS_FMT_RBG888_1X24) + xcsc_rgb_to_ycrcb(csc, &csc->clip_max); + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + csc->cft_out = XVIDC_CSF_YCRCB_422; + dev_dbg(csc->dev, "Media Format Out : YUV 422"); + if (csc->cft_in == MEDIA_BUS_FMT_RBG888_1X24) + xcsc_rgb_to_ycrcb(csc, &csc->clip_max); + break; + case MEDIA_BUS_FMT_VYYUYY8_1X24: + csc->cft_out = XVIDC_CSF_YCRCB_420; + dev_dbg(csc->dev, "Media Format Out : YUV 420"); + if (csc->cft_in == MEDIA_BUS_FMT_RBG888_1X24) + xcsc_rgb_to_ycrcb(csc, &csc->clip_max); + break; + default: + dev_info(csc->dev, "unsupported output video format\n"); + return -EINVAL; + } + xcsc_set_coeff(csc); + + return 0; +} + +/** + * xilinx_csc_bridge_get_output_fmts - output formats supported by csc + * @bridge: bridge instance + * @fmts: Pointer to be updated with formats information + * @count: count of video bus formats + * + * This function provides the output video formats information csc + * Return: 0 on success. + */ +static int xilinx_csc_bridge_get_output_fmts(struct xlnx_bridge *bridge, + const u32 **fmts, u32 *count) +{ + *fmts = xilinx_csc_video_fmts; + *count = ARRAY_SIZE(xilinx_csc_video_fmts); + return 0; +} + +static int xcsc_parse_of(struct xilinx_csc *csc) +{ + int ret; + struct device_node *node = csc->dev->of_node; + + csc->aclk = devm_clk_get(csc->dev, NULL); + if (IS_ERR(csc->aclk)) { + ret = PTR_ERR(csc->aclk); + dev_err(csc->dev, "failed to get aclk %d\n", ret); + return ret; + } + + ret = of_property_read_u32(node, "xlnx,video-width", + &csc->color_depth); + if (ret < 0) { + dev_info(csc->dev, "video width not present in DT\n"); + return ret; + } + if (csc->color_depth != 8 && csc->color_depth != 10 && + csc->color_depth != 12 && csc->color_depth != 16) { + dev_err(csc->dev, "Invalid video width in DT\n"); + return -EINVAL; + } + /* Reset GPIO */ + csc->rst_gpio = devm_gpiod_get(csc->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(csc->rst_gpio)) { + if (PTR_ERR(csc->rst_gpio) != -EPROBE_DEFER) + dev_err(csc->dev, "Reset GPIO not setup in DT"); + return PTR_ERR(csc->rst_gpio); + } + + ret = of_property_read_u32(node, "xlnx,max-height", &csc->max_height); + if (ret < 0) { + dev_err(csc->dev, "xlnx,max-height is missing!"); + return -EINVAL; + } else if (csc->max_height > XCSC_MAX_HEIGHT || + csc->max_height < XCSC_MIN_HEIGHT) { + dev_err(csc->dev, "Invalid height in dt"); + return -EINVAL; + } + + ret = of_property_read_u32(node, "xlnx,max-width", &csc->max_width); + if (ret < 0) { + dev_err(csc->dev, "xlnx,max-width is missing!"); + return -EINVAL; + } else if (csc->max_width > XCSC_MAX_WIDTH || + csc->max_width < XCSC_MIN_WIDTH) { + dev_err(csc->dev, "Invalid width in dt"); + return -EINVAL; + } + + return 0; +} + +static int xilinx_csc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + struct xilinx_csc *csc; + int ret; + + csc = devm_kzalloc(dev, sizeof(*csc), GFP_KERNEL); + if (!csc) + return -ENOMEM; + + csc->dev = dev; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + csc->base = devm_ioremap_resource(dev, res); + if (IS_ERR(csc->base)) + return -ENOMEM; + + platform_set_drvdata(pdev, csc); + ret = xcsc_parse_of(csc); + if (ret < 0) + return ret; + + ret = clk_prepare_enable(csc->aclk); + if (ret) { + dev_err(csc->dev, "failed to enable clock %d\n", ret); + return ret; + } + + gpiod_set_value_cansleep(csc->rst_gpio, XCSC_RESET_DEASSERT); + csc->bridge.enable = &xilinx_csc_bridge_enable; + csc->bridge.disable = &xilinx_csc_bridge_disable; + csc->bridge.set_input = &xilinx_csc_bridge_set_input; + csc->bridge.get_input_fmts = &xilinx_csc_bridge_get_input_fmts; + csc->bridge.set_output = &xilinx_csc_bridge_set_output; + csc->bridge.get_output_fmts = &xilinx_csc_bridge_get_output_fmts; + csc->bridge.of_node = dev->of_node; + + ret = xlnx_bridge_register(&csc->bridge); + if (ret) { + dev_info(csc->dev, "Bridge registration failed\n"); + goto err_clk; + } + + dev_info(csc->dev, "Xilinx VPSS CSC DRM experimental driver probed\n"); + + return 0; + +err_clk: + clk_disable_unprepare(csc->aclk); + return ret; +} + +static int xilinx_csc_remove(struct platform_device *pdev) +{ + struct xilinx_csc *csc = platform_get_drvdata(pdev); + + xlnx_bridge_unregister(&csc->bridge); + clk_disable_unprepare(csc->aclk); + + return 0; +} + +static const struct of_device_id xilinx_csc_of_match[] = { + { .compatible = "xlnx,vpss-csc"}, + { } +}; +MODULE_DEVICE_TABLE(of, xilinx_csc_of_match); + +static struct platform_driver csc_bridge_driver = { + .probe = xilinx_csc_probe, + .remove = xilinx_csc_remove, + .driver = { + .name = "xlnx,csc-bridge", + .of_match_table = xilinx_csc_of_match, + }, +}; + +module_platform_driver(csc_bridge_driver); + +MODULE_AUTHOR("Venkateshwar Rao "); +MODULE_DESCRIPTION("Xilinx FPGA CSC Bridge Driver"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_dptx.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_dptx.c @@ -0,0 +1,4087 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx FPGA DisplayPort TX Subsystem Driver + * + * Copyright (C) 2020 Xilinx, Inc. + * + * Author: Rajesh Gugulothu + * : Venkateshwar Rao G + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "hdcp/xlnx_hdcp_tx.h" + +#define XDPTX_HDCP 0 +#define XDPTX_HDCP2X_OFFSET 0x4000 +#define XDPTX_HDCP_TIMER_OFFSET 0x6000 +#define XDPTX_HDCP1X_OFFSET 0x2000 +#define XDP_TX_HDCP1X_ENABLE 0x400 +#define XDP_TX_HDCP1X_ENABLE_BYPASS_DISABLE_MASK 0x0001 +/* Link configuration registers */ +#define XDPTX_LINKBW_SET_REG 0x0 +#define XDPTX_LANECNT_SET_REG 0x4 +#define XDPTX_DPCD_LANECNT_SET_MASK GENMASK(4, 0) +#define XDPTX_EFRAME_EN_REG 0x8 +#define XDPTX_TRNGPAT_SET_REG 0xc +#define XDPTX_SCRAMBLING_DIS_REG 0x14 +#define XDPTX_DOWNSPREAD_CTL_REG 0x18 +#define XDPTX_DPCD_SPREAD_AMP_MASK BIT(4) +#define XDPTX_SOFT_RST 0x1c +#define XDPTX_SOFT_RST_VIDEO_STREAM_ALL_MASK GENMASK(3, 0) +#define XDPTX_SOFT_RST_HDCP_MASK BIT(8) + +/* GtCtrl Registers */ +#define XDPTX_GTCTL_REG 0x4c +#define XDPTX_GTCTL_VSWING_MASK GENMASK(12, 8) +#define XDPTX_GTCTL_POST_CUR_MASK GENMASK(22, 18) +#define XDPTX_GTCTL_LINE_RATE_MASK GENMASK(2, 1) +#define XDPTX_GTCTL_LINE_RATE_810G 0x03 +#define XDPTX_GTCTL_LINE_RATE_540G 0x02 +#define XDPTX_GTCTL_LINE_RATE_270G 0x01 +#define XDPTX_GTCTL_LINE_RATE_162G 0x00 + +/* GTHE4 */ +#define XVPHY_GTHE4_DIFF_SWING_DP_V0P0 0x01 +#define XVPHY_GTHE4_DIFF_SWING_DP_V0P1 0x02 +#define XVPHY_GTHE4_DIFF_SWING_DP_V0P2 0x05 +#define XVPHY_GTHE4_DIFF_SWING_DP_V0P3 0x0b +#define XVPHY_GTHE4_DIFF_SWING_DP_V1P0 0x02 +#define XVPHY_GTHE4_DIFF_SWING_DP_V1P1 0x05 +#define XVPHY_GTHE4_DIFF_SWING_DP_V1P2 0x07 +#define XVPHY_GTHE4_DIFF_SWING_DP_V2P0 0x04 +#define XVPHY_GTHE4_DIFF_SWING_DP_V2P1 0x07 +#define XVPHY_GTHE4_DIFF_SWING_DP_V3P0 0x08 +#define XVPHY_GTHE4_PREEMP_DP_L0 0x03 +#define XVPHY_GTHE4_PREEMP_DP_L1 0x0d +#define XVPHY_GTHE4_PREEMP_DP_L2 0x16 +#define XVPHY_GTHE4_PREEMP_DP_L3 0x1d + +/* DPTX Core enable registers */ +#define XDPTX_ENABLE_REG 0x80 +#define XDPTX_MAINSTRM_ENABLE_REG 0x84 +#define XDPTX_SCRAMBLER_RESET 0xc0 +#define XDPTX_SCRAMBLER_RESET_MASK BIT(0) +#define XDPTX_MST_CONFIG 0xd0 + +/* AUX channel interface registers */ +#define XDPTX_AUXCMD_REG 0x100 +#define XDPTX_AUX_WRITEFIFO_REG 0x104 +#define XDPTX_AUX_ADDR_REG 0x108 +#define XDPTX_AUXCMD_ADDRONLY_MASK BIT(12) +#define XDPTX_AUXCMD_SHIFT 0x8 +#define XDPTX_AUXCMD_BYTES_SHIFT 0x0 +#define XDPTX_AUX_READ_BIT 0x1 + +#define XDPTX_CLKDIV_REG 0x10c +#define XDPTX_CLKDIV_MHZ 1000000 +#define XDPTX_CLKDIV_AUXFILTER_SHIFT 0x8 + +#define XDPTX_INTR_SIGSTATE_REG 0x130 +#define XDPTX_INTR_SIGHPDSTATE BIT(0) +#define XDPTX_INTR_SIGREQSTATE BIT(1) +#define XDPTX_INTR_SIGRPLYSTATE BIT(2) +#define XDPTX_INTR_RPLYTIMEOUT BIT(3) + +#define XDPTX_AUXREPLY_DATA_REG 0x134 +#define XDPTX_AUXREPLY_CODE_REG 0x138 +#define XDPTX_AUXREPLYCODE_AUXACK_MASK (0) +#define XDPTX_AUXREPLYCODE_I2CACK_MASK (0) + +#define XDPTX_AUXREPLY_DATACNT_REG 0x148 +#define XDPTX_AUXREPLY_DATACNT_MASK GENMASK(7, 0) +#define XDPTX_INTR_STATUS_REG 0x140 +#define XDPTX_INTR_MASK_REG 0x144 +#define XDPTX_INTR_HPDEVENT_MASK BIT(1) +#define XDPTX_INTR_HPDPULSE_MASK BIT(4) +#define XDPTX_INTR_CHBUFUNDFW_MASK GENMASK(21, 16) +#define XDPTX_INTR_CHBUFOVFW_MASK GENMASK(27, 22) +#define XDPTX_INTR_VBLANK_MASK BIT(10) +#define XDPTX_INTR_EXTPKT_TXD_MASK BIT(5) +#define XDPTX_HPD_DURATION_REG 0x150 + +/* Main stream attribute registers */ +#define XDPTX_MAINSTRM_HTOTAL_REG 0x180 +#define XDPTX_MAINSTRM_VTOTAL_REG 0x184 +#define XDPTX_MAINSTRM_POL_REG 0x188 +#define XDPTX_MAINSTRM_POLHSYNC_SHIFT 0x0 +#define XDPTX_MAINSTRM_POLVSYNC_SHIFT 0x1 +#define XDPTX_MAINSTRM_HSWIDTH_REG 0x18c +#define XDPTX_MAINSTRM_VSWIDTH_REG 0x190 +#define XDPTX_MAINSTRM_HRES_REG 0x194 +#define XDPTX_MAINSTRM_VRES_REG 0x198 +#define XDPTX_MAINSTRM_HSTART_REG 0x19c +#define XDPTX_MAINSTRM_VSTART_REG 0x1a0 +#define XDPTX_MAINSTRM_MISC0_REG 0x1a4 +#define XDPTX_MAINSTRM_MISC0_MASK BIT(0) +#define XDPTX_MAINSTRM_MISC0_EXT_VSYNC_MASK BIT(12) +#define XDPTX_MAINSTRM_MISC1_REG 0x1a8 +#define XDPTX_MAINSTRM_MISC1_TIMING_IGNORED_MASK BIT(6) + +#define XDPTX_M_VID_REG 0x1ac +#define XDPTX_TRANSFER_UNITSIZE_REG 0x1b0 +#define XDPTX_DEF_TRANSFER_UNITSIZE 0x40 +#define XDPTX_N_VID_REG 0x1b4 +#define XDPTX_USER_PIXELWIDTH_REG 0x1b8 +#define XDPTX_USER_DATACNTPERLANE_REG 0x1bc +#define XDPTX_MINBYTES_PERTU_REG 0x1c4 +#define XDPTX_FRACBYTES_PERTU_REG 0x1c8 +#define XDPTX_INIT_WAIT_REG 0x1cc + +/* PHY configuration and status registers */ +#define XDPTX_PHYCONFIG_REG 0x200 +#define XDPTX_PHYCONFIG_RESET_MASK BIT(0) +#define XDPTX_PHYCONFIG_GTTXRESET_MASK BIT(1) +#define XDPTX_PHYCONFIG_PMARESET_MASK BIT(8) +#define XDPTX_PHYCONFIG_PCSRESET_MASK BIT(9) +#define XDPTX_PHYCONFIG_ALLRESET_MASK (XDPTX_PHYCONFIG_RESET_MASK | \ + XDPTX_PHYCONFIG_GTTXRESET_MASK | \ + XDPTX_PHYCONFIG_PMARESET_MASK | \ + XDPTX_PHYCONFIG_PCSRESET_MASK) + +#define XDPTX_PHYCLOCK_FBSETTING_REG 0x234 +#define XDPTX_PHYCLOCK_FBSETTING162_MASK 0x1 +#define XDPTX_PHYCLOCK_FBSETTING270_MASK 0x3 +#define XDPTX_PHYCLOCK_FBSETTING810_MASK 0x5 + +#define XDPTX_VS_PE_LEVEL_MAXCOUNT 3 +#define XDPTX_VS_LEVEL_MAXCOUNT 0x5 + +#define XDPTX_PHYSTATUS_REG 0x280 +#define XDPTX_PHYSTATUS_FPGAPLLLOCK_MASK BIT(6) +#define XDPTX_MAX_RATE(bw, lanecnt, bpp) ((bw) * (lanecnt) * 8 / (bpp)) + +#define XDPTX_MISC0_RGB_MASK (0) +#define XDPTX_MISC0_YCRCB422_MASK (5 << 1) +#define XDPTX_MISC0_YCRCB444_MASK GENMASK(3, 2) +#define XDPTX_MISC0_FORMAT_MASK GENMASK(3, 1) +#define XDPTX_MISC0_BPC6_MASK (0 << 5) +#define XDPTX_MISC0_BPC8_MASK BIT(5) +#define XDPTX_MISC0_BPC10_MASK BIT(6) +#define XDPTX_MISC0_BPC12_MASK GENMASK(6, 5) +#define XDPTX_MISC0_BPC16_MASK BIT(7) +#define XDPTX_MISC0_BPC_MASK GENMASK(7, 5) +#define XDPTX_MISC1_YONLY_MASK BIT(7) + +#define XDPTX_MAX_LANES 0x4 +#define XDPTX_MAX_FREQ 3000000 +#define XDPTX_SINK_PWR_CYCLES 3 + +#define XDPTX_REDUCED_BIT_RATE 162000 +#define XDPTX_HIGH_BIT_RATE_1 270000 +#define XDPTX_HIGH_BIT_RATE_2 540000 +#define XDPTX_HIGH_BIT_RATE_3 810000 + +#define XDPTX_V1_2 0x12 +#define XDPTX_V1_4 0x14 + +#define XDP_TRAIN_MAX_SWING_REACHED BIT(2) +#define XDP_TRAIN_PRE_EMPHASIS_SHIFT GENMASK(1, 0) +#define XDP_DPCD_TRAINING_LANEX_SET_MAX_PE_MASK BIT(5) + +#define XDPTX_PHYPRECURSOR_LANE0_REG 0x23c +#define XDPTX_PHYPOSTCURSOR_LANE0_REG 0x24c + +/* Transceiver PHY reset and Differential voltage swing */ +#define XDPTX_PHYVOLTAGE_DIFFLANE0_REG 0x220 +#define XDPTX_VS_LEVEL_OFFSET 0x4 + +#define XDPTX_VTC_BASE 0x1000 + +/* VTC register offsets and bit masks */ +#define XDPTX_VTC_CTL 0x000 +#define XDPTX_VTC_CTL_MASK GENMASK(18, 8) +#define XDPTX_VTC_CTL_GE BIT(2) +#define XDPTX_VTC_CTL_RU BIT(1) + +#define XDPTX_VTC_GASIZE_F0 0x060 +#define XDPTX_VTC_ACTIVE_SIZE_MASK GENMASK(12, 0) + +#define XDPTX_VTC_GFENC 0x068 +#define XDPTX_VTC_GFENC_MASK BIT(6) + +#define XDPTX_VTC_GPOL 0x06c +#define XDPTX_VTC_GPOL_FIELD_ID_POL BIT(6) +#define XDPTX_VTC_ACTIVE_CHROMA_POL BIT(5) +#define XDPTX_VTC_ACTIVE_VIDEO_POL BIT(4) +#define XDPTX_VTC_HSYNC_POL BIT(3) +#define XDPTX_VTC_VSYNC_POL BIT(2) +#define XDPTX_VTC_HBLANK_POL BIT(1) +#define XDPTX_VTC_VBLANK_POL BIT(0) +#define XDPTX_VTC_GPOL_MASK (XDPTX_VTC_VBLANK_POL |\ + XDPTX_VTC_HBLANK_POL |\ + XDPTX_VTC_VSYNC_POL |\ + XDPTX_VTC_HSYNC_POL |\ + XDPTX_VTC_ACTIVE_VIDEO_POL |\ + XDPTX_VTC_ACTIVE_CHROMA_POL) + +#define XDPTX_VTC_INT_GPOL_MASK (XDPTX_VTC_GPOL_FIELD_ID_POL |\ + XDPTX_VTC_ACTIVE_CHROMA_POL |\ + XDPTX_VTC_ACTIVE_VIDEO_POL) + +#define XDPTX_VTC_GHSIZE 0x070 +#define XDPTX_VTC_GHSIZE_FRAME_HSIZE GENMASK(12, 0) + +#define XDPTX_VTC_GVSIZE 0x074 +#define XDPTX_VTC_FIELD1_VSIZE_SHIFT 16 +#define XDPTX_VTC_GVSIZE_FRAME_VSIZE GENMASK(12, 0) + +#define XDPTX_VTC_GHSYNC 0x078 +#define XDPTX_VTC_GH1BPSTART_SHIFT 16 +#define XDPTX_VTC_GHSYNC_END_MASK GENMASK(28, 16) +#define XDPTX_VTC_GHSYNC_START_MASK GENMASK(12, 0) + +#define XDPTX_VTC_GVBHOFF 0x07c +#define XDPTX_VTC_F0VSYNC_HEND_SHIFT 16 +#define XDPTX_VTC_F0VBLANK_HEND_MASK GENMASK(28, 16) +#define XDPTX_VTC_F0VBLANK_HSTART_MASK GENMASK(12, 0) + +#define XDPTX_VTC_GVSYNC 0x080 +#define XDPTX_VTC_F0_VSYNC_VEND_MASK GENMASK(28, 16) +#define XDPTX_VTC_F0_VSYNC_VSTART_MASK GENMASK(12, 0) + +#define XDPTX_VTC_GVSHOFF 0x084 +#define XDPTX_VTC_GVBHOFF_F1 0x088 +#define XDPTX_VTC_GVSYNC_F1 0x08c +#define XDPTX_VTC_GVSHOFF_F1 0x090 +#define XDPTX_VTC_GASIZE_F1 0x094 +/* + * This is sleep time in milliseconds before start training and it can be + * modified as per the monitor + */ +#define XDPTX_POWERON_DELAY_MS 4 +#define XDPTX_AUDIO_CTRL_REG 0x300 +#define XDPTX_AUDIO_EN_MASK BIT(0) +#define XDPTX_AUDIO_MUTE_MASK BIT(16) +#define XDPTX_AUDIO_CHANNELS_REG 0x304 +#define XDPTX_AUDIO_INFO_DATA_REG 0x308 +#define XDPTX_AUDIO_MAUD_REG 0x328 +#define XDPTX_AUDIO_NAUD_REG 0x32C +#define XDP_TX_HDCP2x_ENABLE 0x404 +#define XDP_TX_HDCP2x_ENABLE_BYPASS_DISABLE_MASK BIT(0) +#define XDPTX_AUDIO_INFO_BUFF_STATUS 0x6A0 +#define XDPTX_AUDIO_INFO_BUFF_FULL BIT(0) +#define XDPTX_AUDIO_INFO_BUFF_OVERFLOW BIT(1) + +#define DP_INFOFRAME_FIFO_SIZE_WORDS 8 +#define DP_INFOFRAME_FIFO_SIZE (DP_INFOFRAME_FIFO_SIZE_WORDS * 4) +#define DP_INFOFRAME_HEADER_SIZE 4 +#define DP_AUDIO_INFOFRAME_SIZE 10 +/* infoframe SDP header byte. Please refer section 2.2.5.1.2 in DP1.4 spec */ +#define NON_AUDIOIF_PKT_ID 0x00 +#define NON_AUDIOIF_TYPE 0x07 +#define NON_AUDIOIF_LDATA_BYTECOUNT 0x1d +#define NON_AUDIOIF_SDP_VERSION 0x4c +#define NON_AUDIOIF_DRM_TYPE (0x80 + NON_AUDIOIF_TYPE) +/* DRM infoframe. Please refer section 6.9 in CTA-861G */ +#define CTA_DRMIF_VERSION_NUMBER 0x01 +#define CTA_DRMIF_LENGHT 0x1a + +#define DP_INFOFRAME_SIZE(type) \ + (DP_INFOFRAME_HEADER_SIZE + DP_ ## type ## _INFOFRAME_SIZE) +#define XDPTX_AUDIO_EXT_DATA(NUM) (0x330 + 4 * ((NUM) - 1)) +#define XDPTX_AUDIO_EXT_DATA_2ND_TO_9TH_WORD 8 +#define XDPTX_VSC_SDP_PIXELENC_HEADER_MASK 0x13050700 +#define XDPTX_VSC_SDP_DYNAMIC_RANGE_SHIFT 15 +#define XDPTX_VSC_SDP_BPC_SHIFT 8 +#define XDPTX_VSC_SDP_BPC_MASK GENMASK(2, 0) +#define XDPTX_VSC_SDP_FMT_SHIFT 4 + +#define DP_LINK_BW_SET_MASK GENMASK(4, 0) +#define DP_MAX_TRAINING_TRIES 5 + +#define XDPTX_DP_LANE_COUNT_1 0x01 +#define XDPTX_DP_LANE_COUNT_2 0x02 +#define XDPTX_DP_LANE_COUNT_4 0x04 + +#define XDPTX_DPCD_LANE02_CRDONE_MASK 0x01 +#define XDPTX_DPCD_LANE13_CRDONE_MASK 0x10 + +#define XDPTX_LANE0_CRDONE_MASK 0x0 +#define XDPTX_LANE1_CRDONE_MASK 0x1 +#define XDPTX_LANE2_CRDONE_MASK 0x2 +#define XDPTX_LANE3_CRDONE_MASK 0x3 + +#define XDPTX_HDCP_DPCD_READ 0x00 +#define XDPTX_HDCP_DPCD_WRITE BIT(0) +#define XDPTX_HDCP_STATUS BIT(1) + +#define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) +#define DP_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +/* Flag to get VTC offset from device tree */ +#define XDPTX_VTC_OFFSET_CHANGE BIT(0) + +/* + * CEA speaker placement + * + * FL FLC FC FRC FR FRW + * + * LFE + * + * RL RLC RC RRC RR + */ +enum dp_codec_cea_spk_placement { + FL = BIT(0), /* Front Left */ + FC = BIT(1), /* Front Center */ + FR = BIT(2), /* Front Right */ + FLC = BIT(3), /* Front Left Center */ + FRC = BIT(4), /* Front Right Center */ + RL = BIT(5), /* Rear Left */ + RC = BIT(6), /* Rear Center */ + RR = BIT(7), /* Rear Right */ + RLC = BIT(8), /* Rear Left Center */ + RRC = BIT(9), /* Rear Right Center */ + LFE = BIT(10), /* Low Frequency Effect */ +}; + +/* + * cea Speaker allocation structure + */ +struct dp_codec_cea_spk_alloc { + const int ca_id; + unsigned int n_ch; + unsigned long mask; +}; + +/** + * struct xlnx_dptx_audio_data - Audio data structure + * @buffer: Audio infoframe data buffer + */ +struct xlnx_dptx_audio_data { + u32 buffer[DP_INFOFRAME_FIFO_SIZE_WORDS]; +}; + +union xlnx_dp_iframe_header { + u32 data; + u8 byte[4]; +}; + +union xlnx_dp_iframe_payload { + u32 data[8]; + u8 byte[32]; +}; + +struct xlnx_dp_infoframe { + union xlnx_dp_iframe_header header; + union xlnx_dp_iframe_payload payload; +}; + +/** + * struct xlnx_dp_vscpkt: VSC extended packet structure + * @payload: VSC packet payload bytes from DB0 to DB28 + * @header: VSC packet header + * @bpc: Number of bits per color component + * @fmt: The color format currenctly in use by the video stream + * @dynamic_range: The dynamic range colorimetry currenctly in use by te video stream + * @ycbcr_colorimetry: The ycbcr colorimetry currently in use by te video stream + */ +struct xlnx_dp_vscpkt { + u32 payload[8]; + u32 header; + u32 bpc; + u8 fmt; + u8 dynamic_range; + u8 ycbcr_colorimetry; +}; + +/* + * struct xlnx_dp_link_config - Common link config between source and sink + * @max_rate: Miaximum link rate + * @max_lanes: Maximum number of lanes + */ +struct xlnx_dp_link_config { + int max_rate; + u8 max_lanes; + int link_rate; + u8 lane_count; + u8 cr_done_cnt; + u8 cr_done_oldstate; +}; + +/** + * struct xlnx_dp_tx_link_config - configuration information of the source + * @vs_level: voltage swing level + * @pe_level: pre emphasis level + */ +struct xlnx_dp_tx_link_config { + u8 vs_level; + u8 pe_level; +}; + +/** + * struct xlnx_dp_mode - Configured mode of DisplayPort + * @pclock: pixel clock frequency of current mode + * @bw_code: code for bandwidth(link rate) + * @lane_cnt: number of lanes + */ +struct xlnx_dp_mode { + int pclock; + u8 bw_code; + u8 lane_cnt; +}; + +/** + * struct xlnx_dp_config - Configuration of DisplayPort from DTS + * @max_lanes: Maximum number of lanes + * @max_link_rate: Maximum supported link rate + * @misc0: Misc0 configuration + * @bpp: Bits per pixel + * @bpc: Bits per component + * @num_colors: Number of color components + * @ppc: Pixels per component + * @fmt: Color format + * @audio_enabled: flag to indicate audio is enabled in device tree + * @versal_gt_present: flag to indicate versal-gt property in device tree + * @hdcp2x_enable: flag to indicate hdcp22-enable property in device tree + * @hdcp1x_enable: flag to indicate hdcp-enable property in device tree + */ +struct xlnx_dp_config { + u32 max_lanes; + u32 max_link_rate; + u8 misc0; + u8 bpp; + u8 bpc; + u8 num_colors; + u8 ppc; + u8 fmt; + bool audio_enabled; + bool versal_gt_present; + bool hdcp2x_enable; + bool hdcp1x_enable; +}; + +enum xlnx_dp_train_state { + XLNX_DP_TRAIN_CR = 0, + XLNX_DP_TRAIN_CE = 1, + XLNX_DP_ADJUST_LINKRATE = 2, + XLNX_DP_ADJUST_LANECOUNT = 3, + XLNX_DP_TRAIN_FAILURE = 4, + XLNX_DP_TRAIN_SUCCESS = 5 +}; + +/** + * struct xlnx_dp - Xilinx DisplayPort core + * @dev: device structure + * @encoder: the drm encoder structure + * @connector: the drm connector structure + * @sync_prop: synchronous mode property + * @bpc_prop: bpc mode property + * @aux: aux channel + * @config: IP core configuration from DTS + * @tx_link_config: source configuration + * @tx_hdcp: HDCP configuration + * @hdcpx_keymgmt_base: HDCP key management base address + * @rx_config: sink configuration + * @link_config: common link configuration between IP core and sink device + * @drm: DRM core + * @mode: current mode between IP core and sink device + * @phy: PHY handles for DP lanes + * @axi_lite_clk: axi lite clock + * @tx_vid_clk: tx video clock + * @reset_gpio: reset gpio + * @hpd_work: hot plug detection worker + * @hpd_pulse_work: hot plug pulse detection worker + * @hdcp_cp_irq_work: HDCP content protection message indication worker + * @tx_audio_data: audio data + * @infoframe : IP infoframe data + * @vscpkt: VSC extended packet data + * @cfg: Pointer to DP Feature config struct + * @phy_opts: Opaque generic phy configuration + * @status: connection status + * @dp_base: Base address of DisplayPort Tx subsystem + * @dpms: current dpms state + * @hdcptx_timer_irq: HDCP TX timer interrupt + * @vtc_off: VTC sub-core offset address + * @dpcd: DP configuration data from currently connected sink device + * @train_set: set of training data + * @num_lanes: number of enabled phy lanes + * @enabled: flag to indicate if the device is enabled + * @audio_init: flag to indicate audio is initialized + * @have_edid: flag to indicate if edid is available + * @colorimetry_through_vsc: colorimetry information through vsc packets + * + */ +struct xlnx_dp { + struct device *dev; + struct drm_encoder encoder; + struct drm_connector connector; + struct drm_property *sync_prop; + struct drm_property *bpc_prop; + struct drm_dp_aux aux; + struct xlnx_dp_config config; + struct xlnx_dp_tx_link_config tx_link_config; + struct xlnx_hdcptx tx_hdcp; + struct regmap *hdcpx_keymgmt_base; + struct xlnx_dp_link_config link_config; + struct drm_device *drm; + struct xlnx_dp_mode mode; + struct phy *phy[XDPTX_MAX_LANES]; + struct clk *axi_lite_clk; + struct clk *tx_vid_clk; + struct gpio_desc *reset_gpio; + struct delayed_work hpd_work; + struct delayed_work hpd_pulse_work; + struct delayed_work hdcp_cp_irq_work; + struct xlnx_dptx_audio_data *tx_audio_data; + struct xlnx_dp_infoframe infoframe; + struct xlnx_dp_vscpkt vscpkt; + const struct xlnx_dp_feature *cfg; + union phy_configure_opts phy_opts; + enum drm_connector_status status; + void __iomem *dp_base; + int dpms; + int hdcptx_timer_irq; + u32 vtc_off; + u8 dpcd[DP_RECEIVER_CAP_SIZE]; + u8 train_set[XDPTX_MAX_LANES]; + u8 num_lanes; + unsigned int enabled : 1; + bool audio_init; + bool have_edid; + unsigned int colorimetry_through_vsc : 1; +}; + +/** + * struct xlnx_dp_feature - dt or IP property structure + * @flags: Bitmask of properties enabled in IP or dt + */ +struct xlnx_dp_feature { + u32 flags; +}; + +static const struct xlnx_dp_feature xlnx_dp_cfg_v31 = { + .flags = XDPTX_VTC_OFFSET_CHANGE, +}; + +static const struct xlnx_dp_feature xlnx_dp_cfg_v30 = { + .flags = 0, +}; + +static const struct of_device_id xlnx_dp_of_match[] = { + { .compatible = "xlnx,v-dp-txss-3.0", + .data = (void *)&xlnx_dp_cfg_v30}, + { .compatible = "xlnx,v-dp-txss-3.1", + .data = (void *)&xlnx_dp_cfg_v31}, + { /* end of table */ } +}; + +/* + * dp_codec_channel_alloc: speaker configuration available for CEA + * + * This is an ordered list that must match with dp_codec_8ch_chmaps struct + * The preceding ones have better chances to be selected by + * dp_codec_get_ch_alloc_table_idx(). + */ +static const struct dp_codec_cea_spk_alloc dp_codec_channel_alloc[] = { + { .ca_id = 0x00, .n_ch = 2, + .mask = FL | FR}, + /* 2.1 */ + { .ca_id = 0x01, .n_ch = 4, + .mask = FL | FR | LFE}, + /* Dolby Surround */ + { .ca_id = 0x02, .n_ch = 4, + .mask = FL | FR | FC }, + /* surround51 */ + { .ca_id = 0x0b, .n_ch = 6, + .mask = FL | FR | LFE | FC | RL | RR}, + /* surround40 */ + { .ca_id = 0x08, .n_ch = 6, + .mask = FL | FR | RL | RR }, + /* surround41 */ + { .ca_id = 0x09, .n_ch = 6, + .mask = FL | FR | LFE | RL | RR }, + /* surround50 */ + { .ca_id = 0x0a, .n_ch = 6, + .mask = FL | FR | FC | RL | RR }, + /* 6.1 */ + { .ca_id = 0x0f, .n_ch = 8, + .mask = FL | FR | LFE | FC | RL | RR | RC }, + /* surround71 */ + { .ca_id = 0x13, .n_ch = 8, + .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC }, + /* others */ + { .ca_id = 0x03, .n_ch = 8, + .mask = FL | FR | LFE | FC }, + { .ca_id = 0x04, .n_ch = 8, + .mask = FL | FR | RC}, + { .ca_id = 0x05, .n_ch = 8, + .mask = FL | FR | LFE | RC }, + { .ca_id = 0x06, .n_ch = 8, + .mask = FL | FR | FC | RC }, + { .ca_id = 0x07, .n_ch = 8, + .mask = FL | FR | LFE | FC | RC }, + { .ca_id = 0x0c, .n_ch = 8, + .mask = FL | FR | RC | RL | RR }, + { .ca_id = 0x0d, .n_ch = 8, + .mask = FL | FR | LFE | RL | RR | RC }, + { .ca_id = 0x0e, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | RC }, + { .ca_id = 0x10, .n_ch = 8, + .mask = FL | FR | RL | RR | RLC | RRC }, + { .ca_id = 0x11, .n_ch = 8, + .mask = FL | FR | LFE | RL | RR | RLC | RRC }, + { .ca_id = 0x12, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | RLC | RRC }, + { .ca_id = 0x14, .n_ch = 8, + .mask = FL | FR | FLC | FRC }, + { .ca_id = 0x15, .n_ch = 8, + .mask = FL | FR | LFE | FLC | FRC }, + { .ca_id = 0x16, .n_ch = 8, + .mask = FL | FR | FC | FLC | FRC }, + { .ca_id = 0x17, .n_ch = 8, + .mask = FL | FR | LFE | FC | FLC | FRC }, + { .ca_id = 0x18, .n_ch = 8, + .mask = FL | FR | RC | FLC | FRC }, + { .ca_id = 0x19, .n_ch = 8, + .mask = FL | FR | LFE | RC | FLC | FRC }, + { .ca_id = 0x1a, .n_ch = 8, + .mask = FL | FR | RC | FC | FLC | FRC }, + { .ca_id = 0x1b, .n_ch = 8, + .mask = FL | FR | LFE | RC | FC | FLC | FRC }, + { .ca_id = 0x1c, .n_ch = 8, + .mask = FL | FR | RL | RR | FLC | FRC }, + { .ca_id = 0x1d, .n_ch = 8, + .mask = FL | FR | LFE | RL | RR | FLC | FRC }, + { .ca_id = 0x1e, .n_ch = 8, + .mask = FL | FR | FC | RL | RR | FLC | FRC }, + { .ca_id = 0x1f, .n_ch = 8, + .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, +}; + +static void xlnx_dp_hpd_pulse_work_func(struct work_struct *work); +static int xlnx_dp_txconnected(struct xlnx_dp *dp); + +static inline struct xlnx_dp *encoder_to_dp(struct drm_encoder *encoder) +{ + return container_of(encoder, struct xlnx_dp, encoder); +} + +static inline struct xlnx_dp *connector_to_dp(struct drm_connector *connector) +{ + return container_of(connector, struct xlnx_dp, connector); +} + +static void xlnx_dp_write(void __iomem *base, int offset, u32 val) +{ + writel(val, base + offset); +} + +static u32 xlnx_dp_read(void __iomem *base, int offset) +{ + return readl(base + offset); +} + +static void xlnx_dp_set(void __iomem *base, int offset, u32 set) +{ + xlnx_dp_write(base, offset, xlnx_dp_read(base, offset) | set); +} + +static void xlnx_dp_clr(void __iomem *base, int offset, u32 clr) +{ + xlnx_dp_write(base, offset, xlnx_dp_read(base, offset) & ~clr); +} + +static void xlnx_dp_vtc_set_timing(struct xlnx_dp *dp, + struct drm_display_mode *mode) +{ + u32 reg; + u32 htotal, hactive, hsync_start, hbackporch_start; + u32 vtotal, vactive, vsync_start, vbackporch_start; + u32 hsync_len, hfront_porch, hback_porch; + u32 vsync_len, vfront_porch, vback_porch; + + /* + * TODO : For now driver does not support interlace mode + * In future driver may add interlace support + */ + + /* + * Note that pixels-per-clock for video data and timing is non-existent + * in the Video Timing Controller. There is only a single set of timing + * signals for the video data bus. This means that horizontal (acive + * pixles, hsync, hblank) timing settings can be detected and generated + * only for a multiple of the pixels-per-clock configured in the system. + */ + hactive = mode->hdisplay / dp->config.ppc; + hfront_porch = (mode->hsync_start - mode->hdisplay) / dp->config.ppc; + hback_porch = (mode->htotal - mode->hsync_end) / dp->config.ppc; + hsync_len = (mode->hsync_end - mode->hsync_start) / dp->config.ppc; + htotal = hactive + hfront_porch + hsync_len + hback_porch; + hsync_start = hactive + hfront_porch; + hbackporch_start = hsync_start + hsync_len; + + vactive = mode->vdisplay; + vfront_porch = mode->vsync_start - mode->vdisplay; + vback_porch = mode->vtotal - mode->vsync_end; + vsync_len = mode->vsync_end - mode->vsync_start; + vtotal = vactive + vfront_porch + vsync_len + vback_porch; + vsync_start = vactive + vfront_porch; + vbackporch_start = vsync_start + vsync_len; + + reg = htotal & XDPTX_VTC_GHSIZE_FRAME_HSIZE; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GHSIZE, reg); + + reg = vtotal & XDPTX_VTC_GVSIZE_FRAME_VSIZE; + reg |= reg << XDPTX_VTC_FIELD1_VSIZE_SHIFT; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GVSIZE, reg); + + reg = hactive & XDPTX_VTC_ACTIVE_SIZE_MASK; + reg |= (vactive & XDPTX_VTC_ACTIVE_SIZE_MASK) << + XDPTX_VTC_FIELD1_VSIZE_SHIFT; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GASIZE_F0, reg); + + reg = hsync_start & XDPTX_VTC_GHSYNC_START_MASK; + reg |= (hbackporch_start << XDPTX_VTC_GH1BPSTART_SHIFT) & + XDPTX_VTC_GHSYNC_END_MASK; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GHSYNC, reg); + + reg = vsync_start & XDPTX_VTC_F0_VSYNC_VSTART_MASK; + reg |= (vbackporch_start << XDPTX_VTC_FIELD1_VSIZE_SHIFT) & + XDPTX_VTC_F0_VSYNC_VEND_MASK; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GVSYNC, reg); + xlnx_dp_clr(dp->dp_base, dp->vtc_off + XDPTX_VTC_GFENC, + XDPTX_VTC_GFENC_MASK); + + /* Calculate and update Generator VBlank Hori field 0 */ + reg = hactive & XDPTX_VTC_F0VBLANK_HSTART_MASK; + reg |= (hactive << XDPTX_VTC_F0VSYNC_HEND_SHIFT) & + XDPTX_VTC_F0VBLANK_HEND_MASK; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GVBHOFF, reg); + + /* Calculate and update Generator VSync Hori field 0 */ + reg = hsync_start & XDPTX_VTC_F0VBLANK_HSTART_MASK; + reg |= (hsync_start << XDPTX_VTC_F0VSYNC_HEND_SHIFT) & + XDPTX_VTC_F0VBLANK_HEND_MASK; + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GVSHOFF, reg); + + /* sets all polarities as active high */ + xlnx_dp_write(dp->dp_base, dp->vtc_off + XDPTX_VTC_GPOL, + XDPTX_VTC_GPOL_MASK); + + /* configure timing source */ + xlnx_dp_set(dp->dp_base, dp->vtc_off + XDPTX_VTC_CTL, + XDPTX_VTC_CTL_MASK); + xlnx_dp_set(dp->dp_base, dp->vtc_off + XDPTX_VTC_CTL, + XDPTX_VTC_CTL_RU); +} + +/** + * xlnx_dp_update_bpp - Update the current bpp config + * @dp: DisplayPort IP core structure + * + * Update the current bpp based on the color format: bpc & num_colors. + * Any function that changes bpc or num_colors should call this + * to keep the bpp value in sync. + */ +static void xlnx_dp_update_bpp(struct xlnx_dp *dp) +{ + struct xlnx_dp_config *config = &dp->config; + + config->bpp = dp->config.bpc * dp->config.num_colors; +} + +/** + * xlnx_dp_set_color - Set the color format + * @dp: DisplayPort IP core structure + * @drm_fourcc: Color string, from xlnx_disp_color_enum + * + * This function updates misc register values based on color string. + */ +static void xlnx_dp_set_color(struct xlnx_dp *dp, u32 drm_fourcc) +{ + struct xlnx_dp_config *config = &dp->config; + + config->misc0 &= ~XDPTX_MISC0_FORMAT_MASK; + + switch (drm_fourcc) { + case DRM_FORMAT_XBGR8888: + fallthrough; + case DRM_FORMAT_XRGB8888: + fallthrough; + case DRM_FORMAT_BGR888: + fallthrough; + case DRM_FORMAT_RGB888: + fallthrough; + case DRM_FORMAT_XBGR2101010: + config->misc0 |= XDPTX_MISC0_RGB_MASK; + config->num_colors = 3; + config->fmt = 0x0; + break; + case DRM_FORMAT_VUY888: + fallthrough; + case DRM_FORMAT_XVUY8888: + fallthrough; + case DRM_FORMAT_Y8: + fallthrough; + case DRM_FORMAT_XVUY2101010: + fallthrough; + case DRM_FORMAT_Y10: + config->misc0 |= XDPTX_MISC0_YCRCB444_MASK; + config->num_colors = 3; + config->fmt = 0x1; + break; + case DRM_FORMAT_YUYV: + fallthrough; + case DRM_FORMAT_UYVY: + fallthrough; + case DRM_FORMAT_NV16: + fallthrough; + case DRM_FORMAT_XV20: + config->misc0 |= XDPTX_MISC0_YCRCB422_MASK; + config->num_colors = 2; + config->fmt = 0x2; + break; + default: + dev_dbg(dp->dev, "Warning: Unknown drm_fourcc format :%d\n", + drm_fourcc); + config->misc0 |= XDPTX_MISC0_RGB_MASK; + } + xlnx_dp_update_bpp(dp); +} + +/** + * xlnx_dp_init_phy - Initialize the phy + * @dp: DisplayPort IP core structure + * + * Initialize the phy. + * + * Return: 0 if the phy instances are initialized correctly, or the error code + * returned from the callee functions. + */ +static int xlnx_dp_init_phy(struct xlnx_dp *dp) +{ + unsigned int i; + int ret; + + xlnx_dp_clr(dp->dp_base, XDPTX_PHYCONFIG_REG, + XDPTX_PHYCONFIG_ALLRESET_MASK); + + for (i = 0; i < XDPTX_MAX_LANES; i++) { + ret = phy_init(dp->phy[i]); + if (ret) { + dev_err(dp->dev, + "failed to init phy lane %d\n", i); + return ret; + } + } + + return ret; +} + +/** + * xlnx_dp_exit_phy - Exit the phy + * @dp: DisplayPort IP core structure + * + * Exit the phy. + */ +static void xlnx_dp_exit_phy(struct xlnx_dp *dp) +{ + unsigned int i; + int ret; + + for (i = 0; i < XDPTX_MAX_LANES; i++) { + ret = phy_exit(dp->phy[i]); + if (ret) + dev_err(dp->dev, "fail to exit phy(%d) %d\n", i, ret); + dp->phy[i] = NULL; + } +} + +/** + * xlnx_dp_phy_ready - check if PHY is ready + * @dp: DisplayPort IP core structure + * + * check if PHY is ready. If PHY is not ready, wait 1ms to check for 100 times. + * This amount of delay was suggested by IP designer. + * + * Return: 0 if PHY is ready, or -ENODEV if PHY is not ready. + */ +static int xlnx_dp_phy_ready(struct xlnx_dp *dp) +{ + u32 i, reg, ready; + + ready = (1 << XDPTX_MAX_LANES) - 1; + ready |= XDPTX_PHYSTATUS_FPGAPLLLOCK_MASK; + + /* Wait for 100ms. This should be enough time for PHY to be ready */ + for (i = 0; ; i++) { + reg = xlnx_dp_read(dp->dp_base, XDPTX_PHYSTATUS_REG); + if ((reg & ready) == ready) + return 0; + if (i == 100) { + dev_err(dp->dev, "PHY isn't ready\n"); + return -ENODEV; + } + usleep_range(1000, 1100); + } + + return 0; +} + +/** + * xlnx_dp_tx_set_vswing_preemp - This function sets current voltage swing and + * pre-emphasis level settings from the link_config structure to hardware. + * @dp: DisplayPort IP core structure + * @aux_data: Aux_data is a pointer to the array used for preparing a burst + * write over the AUX channel. + */ +static void xlnx_dp_tx_set_vswing_preemp(struct xlnx_dp *dp, u8 *aux_data) +{ + static const u32 tx_pe_levels[] = { 0x00, 0x0e, 0x14, 0x1b }; + static const u8 tx_vs_levels[] = { 0x2, 0x5, 0x8, 0xf }; + u32 pe_level, vs_level; + u8 data, i; + + u8 vs_level_rx = dp->tx_link_config.vs_level; + u8 pe_level_rx = dp->tx_link_config.pe_level; + + pe_level = tx_pe_levels[pe_level_rx]; + vs_level = tx_vs_levels[vs_level_rx]; + + /* + * Redriver in path requires different voltage-swing and pre-emphasis + * values. Below case assumes there is no redriver in the path so + * voltage-swing compensation offset is used when pre-emphasis is used. + * See the VESA DisplayPort v1.4 Specification, section 3.6.1.1. + */ + if (!pe_level_rx) + vs_level += XDPTX_VS_LEVEL_OFFSET; + + data = (pe_level_rx << XDP_TRAIN_PRE_EMPHASIS_SHIFT) | + vs_level_rx; + + if (vs_level_rx == XDPTX_VS_PE_LEVEL_MAXCOUNT) + data |= XDP_TRAIN_MAX_SWING_REACHED; + if (pe_level_rx == XDPTX_VS_PE_LEVEL_MAXCOUNT) + data |= XDP_DPCD_TRAINING_LANEX_SET_MAX_PE_MASK; + + memset(aux_data, data, XDPTX_MAX_LANES); + + for (i = 0; i < dp->mode.lane_cnt; i++) { + xlnx_dp_write(dp->dp_base, + XDPTX_PHYPRECURSOR_LANE0_REG + 4 * i, 0x0); + xlnx_dp_write(dp->dp_base, + XDPTX_PHYVOLTAGE_DIFFLANE0_REG + 4 * i, vs_level); + xlnx_dp_write(dp->dp_base, + XDPTX_PHYPOSTCURSOR_LANE0_REG + 4 * i, pe_level); + } +} + +static int config_gt_control_linerate(struct xlnx_dp *dp, int bw_code) +{ + u32 data, regval; + + switch (bw_code) { + case DP_LINK_BW_1_62: + data = XDPTX_GTCTL_LINE_RATE_162G; + break; + case DP_LINK_BW_2_7: + data = XDPTX_GTCTL_LINE_RATE_270G; + break; + case DP_LINK_BW_5_4: + data = XDPTX_GTCTL_LINE_RATE_540G; + break; + case DP_LINK_BW_8_1: + data = XDPTX_GTCTL_LINE_RATE_810G; + break; + default: + data = XDPTX_GTCTL_LINE_RATE_810G; + } + + regval = xlnx_dp_read(dp->dp_base, XDPTX_GTCTL_REG); + regval &= ~XDPTX_GTCTL_LINE_RATE_MASK; + regval |= FIELD_PREP(XDPTX_GTCTL_LINE_RATE_MASK, data); + xlnx_dp_write(dp->dp_base, XDPTX_GTCTL_REG, regval); + + /* Wait for PHY ready */ + return xlnx_dp_phy_ready(dp); +} + +static int xlnx_dp_tx_gt_control_init(struct xlnx_dp *dp) +{ + u32 data; + int ret; + + /* Setting initial vswing */ + data = xlnx_dp_read(dp->dp_base, XDPTX_GTCTL_REG); + data &= ~XDPTX_GTCTL_VSWING_MASK; + data |= FIELD_PREP(XDPTX_GTCTL_VSWING_MASK, 0x05); + xlnx_dp_write(dp->dp_base, XDPTX_GTCTL_REG, data); + + xlnx_dp_clr(dp->dp_base, XDPTX_GTCTL_REG, 0x01); + ret = xlnx_dp_phy_ready(dp); + if (ret < 0) + return ret; + + /* Setting initial link rate */ + ret = config_gt_control_linerate(dp, DP_LINK_BW_5_4); + if (ret) { + dev_err(dp->dev, "Default Line Rate setting Failed\n"); + return ret; + } + + return 0; +} + +/** + * xlnx_dp_set_train_patttern - This function sets the training pattern to be + * used during link training for both the DisplayPort TX core and Rx core. + * @dp: DisplayPort IP core structure + * @pattern: pattern selects the pattern to be used. One of the following + * - DP_TRAINING_PATTERN_DISABLE + * - DP_TRAINING_PATTERN_1 + * - DP_TRAINING_PATTERN_2 + * - DP_TRAINING_PATTERN_3 + * - DP_TRAINING_PATTERN_4 + * + * Returns: + * - 0 on success or negative error code on failure + */ +static int xlnx_dp_set_train_patttern(struct xlnx_dp *dp, u32 pattern) +{ + int ret; + u8 aux_data[5]; + + xlnx_dp_write(dp->dp_base, XDPTX_TRNGPAT_SET_REG, pattern); + aux_data[0] = pattern; + + /* write scrambler disable to DisplayPort TX core */ + switch (pattern) { + case DP_TRAINING_PATTERN_DISABLE: + xlnx_dp_write(dp->dp_base, XDPTX_SCRAMBLING_DIS_REG, 0); + break; + case DP_TRAINING_PATTERN_1: + case DP_TRAINING_PATTERN_2: + case DP_TRAINING_PATTERN_3: + aux_data[0] |= DP_LINK_SCRAMBLING_DISABLE; + xlnx_dp_write(dp->dp_base, XDPTX_SCRAMBLING_DIS_REG, 1); + break; + case DP_TRAINING_PATTERN_4: + xlnx_dp_write(dp->dp_base, XDPTX_SCRAMBLING_DIS_REG, 0); + break; + default: + break; + } + + /* Make the adjustment to both the DisplayPort TX core and the RX */ + xlnx_dp_tx_set_vswing_preemp(dp, &aux_data[1]); + + if (pattern == DP_TRAINING_PATTERN_DISABLE) + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_PATTERN_SET, + aux_data, 1); + else + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_PATTERN_SET, + aux_data, 5); + + return ret; +} + +/** + * xlnx_dp_tx_pe_vs_adjust_handler - Calculate and configure pe and vs values + * @dp: DisplayPort IP core structure + * @dp_phy_opts: phy configuration structure + * + * This function adjusts the pre emphasis and voltage swing values of phy. + */ +static void xlnx_dp_tx_pe_vs_adjust_handler(struct xlnx_dp *dp, + struct phy_configure_opts_dp *dp_phy_opts) +{ + u8 preemp = 0, diff_swing = 0; + u32 data; + + switch (dp_phy_opts->pre[0]) { + case 0: + preemp = XVPHY_GTHE4_PREEMP_DP_L0; + break; + case 1: + preemp = XVPHY_GTHE4_PREEMP_DP_L1; + break; + case 2: + preemp = XVPHY_GTHE4_PREEMP_DP_L2; + break; + case 3: + preemp = XVPHY_GTHE4_PREEMP_DP_L3; + break; + } + + switch (dp_phy_opts->voltage[0]) { + case 0: + switch (dp_phy_opts->pre[0]) { + case 0: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V0P0; + break; + case 1: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V0P1; + break; + case 2: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V0P2; + break; + case 3: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V0P3; + break; + } + break; + case 1: + switch (dp_phy_opts->pre[0]) { + case 0: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V1P0; + break; + case 1: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V1P1; + break; + case 2: + fallthrough; + case 3: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V1P2; + break; + } + break; + case 2: + switch (dp_phy_opts->pre[0]) { + case 0: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V2P0; + break; + case 1: + fallthrough; + case 2: + fallthrough; + case 3: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V2P1; + break; + } + break; + case 3: + diff_swing = XVPHY_GTHE4_DIFF_SWING_DP_V3P0; + break; + } + + data = xlnx_dp_read(dp->dp_base, XDPTX_GTCTL_REG); + data &= ~(XDPTX_GTCTL_POST_CUR_MASK | XDPTX_GTCTL_VSWING_MASK); + data |= FIELD_PREP(XDPTX_GTCTL_VSWING_MASK, diff_swing) | + FIELD_PREP(XDPTX_GTCTL_POST_CUR_MASK, preemp); + xlnx_dp_write(dp->dp_base, XDPTX_GTCTL_REG, data); + + dp_phy_opts->set_voltages = 0; +} + +/** + * xlnx_dp_tx_adj_vswing_preemp - Sets voltage swing and pre-emphasis levels + * using the adjustment requests obtained from the RX device + * @dp:Pointer to xlnx_dp structure + * @link_status: An array of link status register + * + * This function sets new voltage swing and pre-emphasis levels using the + * adjustment requests obtained from the sink. + * + * Return: 0 if the new levels were written successfully. + * error value on failure. + */ +static int xlnx_dp_tx_adj_vswing_preemp(struct xlnx_dp *dp, u8 link_status[6]) +{ + struct phy_configure_opts_dp *phy_cfg = &dp->phy_opts.dp; + int ret; + u8 i, aux_data[4]; + u8 vs_level_adj_req[4]; + u8 pe_level_adj_req[4]; + u8 max_lanes = dp->link_config.max_lanes; + + /* + * Analyze the adjustment requests for changes in voltage swing and + * pre-emphasis levels. + */ + vs_level_adj_req[0] = FIELD_GET(DP_ADJUST_VOLTAGE_SWING_LANE0_MASK, + link_status[4]); + vs_level_adj_req[1] = FIELD_GET(DP_ADJUST_VOLTAGE_SWING_LANE1_MASK, + link_status[4]); + vs_level_adj_req[2] = FIELD_GET(DP_ADJUST_VOLTAGE_SWING_LANE0_MASK, + link_status[5]); + vs_level_adj_req[3] = FIELD_GET(DP_ADJUST_VOLTAGE_SWING_LANE1_MASK, + link_status[5]); + pe_level_adj_req[0] = FIELD_GET(DP_ADJUST_PRE_EMPHASIS_LANE0_MASK, + link_status[4]); + pe_level_adj_req[1] = FIELD_GET(DP_ADJUST_PRE_EMPHASIS_LANE1_MASK, + link_status[4]); + pe_level_adj_req[2] = FIELD_GET(DP_ADJUST_PRE_EMPHASIS_LANE0_MASK, + link_status[5]); + pe_level_adj_req[3] = FIELD_GET(DP_ADJUST_PRE_EMPHASIS_LANE1_MASK, + link_status[5]); + + /* + * change the drive settings to match the adjustment requests. Use the + * greatest level requested. + */ + dp->tx_link_config.vs_level = 0; + dp->tx_link_config.pe_level = 0; + for (i = 0; i < dp->mode.lane_cnt ; i++) { + if (vs_level_adj_req[i] > dp->tx_link_config.vs_level) + dp->tx_link_config.vs_level = vs_level_adj_req[i]; + if (pe_level_adj_req[i] > dp->tx_link_config.pe_level) + dp->tx_link_config.pe_level = pe_level_adj_req[i]; + } + + /* + * Verify that the voltage swing and pre-emphasis combination is + * allowed. Some combinations will result in differential peak-to-peak + * voltage that is outside the permissible range. See the VESA + * DisplayPort v1.4 Specification, section 3.1.5.2. + * The valid combinations are: + * PE=0 PE=1 PE=2 PE=3 + * VS=0 Valid Valid Valid Valid + * VS=1 Valid Valid Valid + * VS=2 Valid Valid + * VS=3 Valid + */ + if (dp->tx_link_config.pe_level > (4 - dp->tx_link_config.vs_level)) + dp->tx_link_config.pe_level = 4 - dp->tx_link_config.vs_level; + + /* + * Make the adjustments to both the DisplayPort TX core and the RX + * device. + */ + xlnx_dp_tx_set_vswing_preemp(dp, aux_data); + /* + * Write the voltage swing and pre-emphasis levels for each lane to the + * RX device. + */ + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, + &aux_data[0], 4); + if (ret < 0) + return ret; + + phy_cfg->lanes = max_lanes; + phy_cfg->pre[0] = dp->tx_link_config.pe_level; + phy_cfg->voltage[0] = dp->tx_link_config.vs_level; + phy_cfg->set_voltages = 1; + + if (!dp->config.versal_gt_present) + phy_configure(dp->phy[0], &dp->phy_opts); + else + xlnx_dp_tx_pe_vs_adjust_handler(dp, &dp->phy_opts.dp); + + return 0; +} + +/** + * xlnx_dp_check_clock_recovery - This function checks if the RX device's DPCD + * indicates that the clock recovery sequence during link training was + * successful - the RX device's link clock and data recovery unit has realized + * and maintained the frequency lock for all the lanes currently in use. + * @dp: DisplayPort IP core structure + * @lane_cnt: Number of lanes in use + * + * Return: 0 if the RX device's clock recovery PLL has achieved frequency lock + * for all the lanes in use.Othewise returns error value. + */ +static int xlnx_dp_check_clock_recovery(struct xlnx_dp *dp, u8 lane_cnt) +{ + struct xlnx_dp_link_config *link_config = &dp->link_config; + int ret; + u8 link_status[DP_LINK_STATUS_SIZE]; + + ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); + if (ret < 0) + return ret; + + switch (lane_cnt) { + case XDPTX_DP_LANE_COUNT_4: + if (!(link_status[0] & XDPTX_DPCD_LANE02_CRDONE_MASK)) { + link_config->cr_done_cnt = XDPTX_LANE0_CRDONE_MASK; + return 1; + } + if (!(link_status[0] & XDPTX_DPCD_LANE13_CRDONE_MASK)) { + link_config->cr_done_cnt = XDPTX_LANE1_CRDONE_MASK; + return 1; + } + if (!(link_status[1] & XDPTX_DPCD_LANE02_CRDONE_MASK)) { + link_config->cr_done_cnt = XDPTX_LANE2_CRDONE_MASK; + return 1; + } + if (!(link_status[1] & XDPTX_DPCD_LANE13_CRDONE_MASK)) { + link_config->cr_done_cnt = XDPTX_LANE3_CRDONE_MASK; + return 1; + } + link_config->cr_done_cnt = 0x4; + fallthrough; + case XDPTX_DP_LANE_COUNT_2: + if (!(link_status[0] & XDPTX_DPCD_LANE02_CRDONE_MASK)) { + link_config->cr_done_cnt = 0x0; + return 1; + } + if (!(link_status[0] & XDPTX_DPCD_LANE13_CRDONE_MASK)) { + link_config->cr_done_cnt = 0x1; + return 1; + } + link_config->cr_done_cnt = 0x2; + fallthrough; + case XDPTX_DP_LANE_COUNT_1: + if (!(link_status[0] & XDPTX_DPCD_LANE02_CRDONE_MASK)) { + link_config->cr_done_cnt = 0x0; + return 1; + } + link_config->cr_done_cnt = 0x1; + break; + default: + break; + } + + return 0; +} + +static int xlnx_dp_set_linkrate(struct xlnx_dp *dp, u8 bw_code) +{ + struct phy_configure_opts_dp *phy_cfg = &dp->phy_opts.dp; + int ret; + u32 reg, lrate_val = 0, val; + u8 lane_count = dp->mode.lane_cnt; + + if (!xlnx_dp_txconnected(dp)) { + dev_dbg(dp->dev, "display is not connected"); + return connector_status_disconnected; + } + + dp->mode.bw_code = bw_code; + + switch (bw_code) { + case DP_LINK_BW_1_62: + reg = XDPTX_PHYCLOCK_FBSETTING162_MASK; + phy_cfg->link_rate = XDPTX_REDUCED_BIT_RATE / 100; + if (dp->config.versal_gt_present) + lrate_val = XDPTX_GTCTL_LINE_RATE_162G; + break; + case DP_LINK_BW_2_7: + reg = XDPTX_PHYCLOCK_FBSETTING270_MASK; + phy_cfg->link_rate = XDPTX_HIGH_BIT_RATE_1 / 100; + if (dp->config.versal_gt_present) + lrate_val = XDPTX_GTCTL_LINE_RATE_270G; + break; + case DP_LINK_BW_5_4: + reg = XDPTX_PHYCLOCK_FBSETTING810_MASK; + phy_cfg->link_rate = XDPTX_HIGH_BIT_RATE_2 / 100; + if (dp->config.versal_gt_present) + lrate_val = XDPTX_GTCTL_LINE_RATE_540G; + break; + case DP_LINK_BW_8_1: + reg = XDPTX_PHYCLOCK_FBSETTING810_MASK; + phy_cfg->link_rate = XDPTX_HIGH_BIT_RATE_3 / 100; + if (dp->config.versal_gt_present) + lrate_val = XDPTX_GTCTL_LINE_RATE_810G; + break; + default: + reg = XDPTX_PHYCLOCK_FBSETTING810_MASK; + phy_cfg->link_rate = XDPTX_HIGH_BIT_RATE_3 / 100; + if (dp->config.versal_gt_present) + lrate_val = XDPTX_GTCTL_LINE_RATE_810G; + } + + /* + * set the clock frequency for the DisplayPort PHY corresponding + * to a desired link rate + */ + val = xlnx_dp_read(dp->dp_base, XDPTX_ENABLE_REG); + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 0); + xlnx_dp_write(dp->dp_base, XDPTX_PHYCLOCK_FBSETTING_REG, reg); + if (val) + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 1); + /* Wait for PHY ready */ + ret = xlnx_dp_phy_ready(dp); + if (ret < 0) + return ret; + + /* write new link rate to the DisplayPort TX core */ + xlnx_dp_write(dp->dp_base, XDPTX_LINKBW_SET_REG, bw_code); + /* write new link rate to the RX device */ + ret = drm_dp_dpcd_writeb(&dp->aux, DP_LINK_BW_SET, bw_code); + if (ret < 0) { + dev_err(dp->dev, "failed to set DP bandwidth\n"); + return ret; + } + /* configure video phy controller to new link rate */ + phy_cfg->set_rate = 1; + phy_cfg->lanes = lane_count; + if (!dp->config.versal_gt_present) + phy_configure(dp->phy[0], &dp->phy_opts); + + if (dp->config.versal_gt_present) { + val = xlnx_dp_read(dp->dp_base, XDPTX_GTCTL_REG); + val &= ~XDPTX_GTCTL_LINE_RATE_MASK; + val |= FIELD_PREP(XDPTX_GTCTL_LINE_RATE_MASK, lrate_val); + xlnx_dp_write(dp->dp_base, XDPTX_GTCTL_REG, val); + } + + return 0; +} + +static int xlnx_dp_set_lanecount(struct xlnx_dp *dp, u8 lane_cnt) +{ + int ret; + u8 data; + + dp->mode.lane_cnt = lane_cnt; + xlnx_dp_write(dp->dp_base, XDPTX_LANECNT_SET_REG, lane_cnt); + + ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); + if (ret < 0) { + dev_err(dp->dev, "DPCD read retry fails"); + return ret; + } + + data &= ~XDPTX_DPCD_LANECNT_SET_MASK; + data |= dp->mode.lane_cnt; + ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, data); + if (ret < 0) { + dev_err(dp->dev, "failed to set lane count\n"); + return ret; + } + + return 0; +} + +/** + * xlnx_dp_check_link_status - This function checks if the receiver has + * achieved and maintained clock recovery, channel equalization, symbol lock, and + * interlane alignment for all lanes currently in use + * @dp: DisplayPort IP core structure + * + * Return: 0 if link status is successfully. + * error value on failure. + */ +static int xlnx_dp_check_link_status(struct xlnx_dp *dp) +{ + int ret; + u8 link_status[DP_LINK_STATUS_SIZE]; + u8 retry = 0; + + memset(link_status, 0, sizeof(link_status)); + + if (!xlnx_dp_txconnected(dp)) { + dev_dbg(dp->dev, "display is not connected"); + return connector_status_disconnected; + } + + for (retry = 0; retry < 5; retry++) { + ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); + if (ret < 0) + return ret; + + if (drm_dp_clock_recovery_ok(link_status, dp->mode.lane_cnt) || + drm_dp_channel_eq_ok(link_status, dp->mode.lane_cnt)) + return 0; + } + + return -EINVAL; +} + +static int xlnx_dp_post_training(struct xlnx_dp *dp) +{ + int ret; + u8 data; + + if (dp->dpcd[DP_DPCD_REV] == XDPTX_V1_4) { + ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); + if (ret < 0) { + dev_dbg(dp->dev, "DPCD read first try fails"); + ret = drm_dp_dpcd_readb(&dp->aux, + DP_LANE_COUNT_SET, &data); + if (ret < 0) { + dev_err(dp->dev, "DPCD read retry fails"); + return ret; + } + } + + /* + * Post Link Training ; An upstream device with a DPTX sets + * this bit to 1 to grant the POST_LT_ADJ_REQ sequence by the + * downstream DPRX if the downstream DPRX supports + * POST_LT_ADJ_REQ + */ + data |= 0x20; + ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, data); + if (ret < 0) { + dev_dbg(dp->dev, "DPCD write first try fails"); + ret = drm_dp_dpcd_writeb(&dp->aux, + DP_LANE_COUNT_SET, data); + if (ret < 0) { + dev_err(dp->dev, "DPCD write retry fails"); + return ret; + } + } + } + + ret = xlnx_dp_check_link_status(dp); + if (ret < 0) + return ret; + + ret = xlnx_dp_set_train_patttern(dp, DP_TRAINING_PATTERN_DISABLE); + if (ret < 0) { + dev_err(dp->dev, "failed to disable training pattern\n"); + return ret; + } + + return 0; +} + +/** + * xlnx_dp_link_train_cr - Train clock recovery + * @dp: DisplayPort IP core structure + * + * Return: 0 if clock recovery train is done successfully, or corresponding + * error code. + */ +static int xlnx_dp_link_train_cr(struct xlnx_dp *dp) +{ + struct xlnx_dp_tx_link_config *link_config = &dp->tx_link_config; + struct xlnx_dp_link_config *config = &dp->link_config; + int ret; + u16 max_tries; + u8 prev_vs_level = 0, same_vs_level_count = 0; + u8 link_status[DP_LINK_STATUS_SIZE]; + u8 lane_cnt = dp->mode.lane_cnt; + bool cr_done = 0; + + /* start from minimal vs and pe levels */ + dp->tx_link_config.vs_level = 0; + dp->tx_link_config.pe_level = 0; + + ret = xlnx_dp_set_train_patttern(dp, DP_TRAINING_PATTERN_1); + if (ret < 0) + return XLNX_DP_TRAIN_FAILURE; + + /* + * 256 loops should be maximum iterations for 4 lanes and 4 values. + * So, This loop should exit before 512 iterations + */ + for (max_tries = 0; max_tries < 512; max_tries++) { + /* + * Obtain the required delay for clock recovery as specified + * by the RX device. + * Wait delay specified in TRAINING_AUX_RD_INTERVAL(0x0E) + */ + drm_dp_link_train_clock_recovery_delay(&dp->aux, dp->dpcd); + /* + * check if all lanes have realized and maintained the + * frequency lock and get adjustment requests. + */ + ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); + if (ret < 0) + return XLNX_DP_TRAIN_FAILURE; + + cr_done = xlnx_dp_check_clock_recovery(dp, lane_cnt); + if (!cr_done) + return XLNX_DP_TRAIN_CE; + /* + * check if the same voltage swing for each lane has been + * used 5 consecutive times. + */ + if (prev_vs_level == link_config->vs_level) { + same_vs_level_count++; + } else { + same_vs_level_count = 0; + prev_vs_level = link_config->vs_level; + } + + if (same_vs_level_count >= XDPTX_VS_LEVEL_MAXCOUNT) + break; + + if (link_config->vs_level == XDPTX_VS_PE_LEVEL_MAXCOUNT) + break; + /* Adjust the drive settings as requested by the RX device */ + ret = xlnx_dp_tx_adj_vswing_preemp(dp, link_status); + if (ret < 0) + return XLNX_DP_TRAIN_FAILURE; + } + + if (dp->mode.bw_code == DP_LINK_BW_1_62) { + if (config->cr_done_cnt != 0x4 && config->cr_done_cnt != 0x0) { + ret = xlnx_dp_set_train_patttern(dp, DP_TRAINING_PATTERN_DISABLE); + if (ret < 0) { + dev_err(dp->dev, "failed to disable training pattern\n"); + return ret; + } + + ret = xlnx_dp_set_linkrate(dp, DP_LINK_BW_8_1); + if (ret < 0) { + dev_err(dp->dev, "failed to set link rate\n"); + return ret; + } + + ret = xlnx_dp_set_lanecount(dp, config->cr_done_cnt); + if (ret < 0) { + dev_err(dp->dev, "failed to set lane count\n"); + return ret; + } + config->cr_done_oldstate = config->cr_done_cnt; + + return XLNX_DP_TRAIN_CR; + } + } + + return XLNX_DP_ADJUST_LINKRATE; +} + +/** + * xlnx_dp_adjust_linkrate - Adjust the link rate + * @dp: DisplayPort core structure + * + * This function is reached if either the clock recovery or the channel + * equalization process failed during training. As a result, the data rate will + * be downshifted and training will be re-attempted at the reduced data rate. If + * the data rate is already at 1.62 Gbps, a downshited in lane count will be + * attempted. + * + * Return: The next training state: + * - XLNX_DP_ADJUST_LANECOUNT if the minimal data rate is already in use. + * re-attempt training at a reduced lane count. + * - XLNX_DP_TRAIN_CR otherwise. Re-attempt training. + */ +static int xlnx_dp_adjust_linkrate(struct xlnx_dp *dp) +{ + int ret; + u8 bw_code; + + switch (dp->mode.bw_code) { + case DP_LINK_BW_8_1: + bw_code = DP_LINK_BW_5_4; + break; + case DP_LINK_BW_5_4: + bw_code = DP_LINK_BW_2_7; + break; + case DP_LINK_BW_2_7: + bw_code = DP_LINK_BW_1_62; + break; + default: + /* + * Already at the lowest link rate. Try reducing the lane + * count next + */ + return XLNX_DP_ADJUST_LANECOUNT; + } + + ret = xlnx_dp_set_linkrate(dp, bw_code); + if (ret < 0) { + dev_err(dp->dev, "failed to set link rate\n"); + return XLNX_DP_TRAIN_FAILURE; + } + + ret = xlnx_dp_set_lanecount(dp, dp->link_config.cr_done_oldstate); + if (ret < 0) { + dev_err(dp->dev, "failed to set lane count\n"); + return XLNX_DP_TRAIN_FAILURE; + } + + return XLNX_DP_TRAIN_CR; +} + +/** + * xlnx_dp_adjust_lanecount - Adjust the lane count + * @dp: DisplayPort core structure + * + * This function is reached if either the clock recovery or the channel + * equalization process failed during training. As a result, the number of lanes + * will be downshifted and training will be re-attempted at this lower lane + * count. + * + * note: Training will be re-attempted with the maximum data rate being used + * with the reduced lane count to train the main link at the maximum bandwidth + * possible. + * + * Return: The next training state: + * - XLNX_DP_TRAIN_FAILURE if only one lane is already in use + * - XLNX_DP_TRAIN_CR otherwise. Re-attempt training + */ +static int xlnx_dp_adjust_lanecount(struct xlnx_dp *dp) +{ + int max_rate = dp->link_config.max_rate, ret; + u8 bw_code = drm_dp_link_rate_to_bw_code(max_rate), lane_cnt; + + switch (dp->mode.lane_cnt) { + case XDPTX_DP_LANE_COUNT_4: + lane_cnt = XDPTX_DP_LANE_COUNT_2; + break; + case XDPTX_DP_LANE_COUNT_2: + lane_cnt = XDPTX_DP_LANE_COUNT_1; + break; + default: + dev_err(dp->dev, " Training failed at lowest linkrate and lane count\n"); + return XLNX_DP_TRAIN_FAILURE; + } + + ret = xlnx_dp_set_linkrate(dp, bw_code); + if (ret < 0) { + dev_err(dp->dev, "failed to set link rate\n"); + return XLNX_DP_TRAIN_FAILURE; + } + + ret = xlnx_dp_set_lanecount(dp, lane_cnt); + if (ret < 0) { + dev_err(dp->dev, "failed to set lane count\n"); + return XLNX_DP_TRAIN_FAILURE; + } + + return XLNX_DP_TRAIN_CR; +} + +/** + * xlnx_dp_link_train_ce - Train channel equalization + * @dp: DisplayPort IP core structure + * + * Return: 0 if channel equalization train is done successfully, or + * corresponding error code. + */ + +static int xlnx_dp_link_train_ce(struct xlnx_dp *dp) +{ + struct xlnx_dp_link_config *config = &dp->link_config; + struct xlnx_dp_mode *mode = &dp->mode; + int ret; + u32 i; + u8 pat, link_status[DP_LINK_STATUS_SIZE]; + u8 lane_cnt = dp->mode.lane_cnt; + bool ce_done, cr_done; + + if (dp->dpcd[DP_DPCD_REV] == XDPTX_V1_4 && + dp->dpcd[DP_MAX_DOWNSPREAD] & DP_TPS4_SUPPORTED) { + pat = DP_TRAINING_PATTERN_4; + } else if (dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { + pat = DP_TRAINING_PATTERN_3; + } else { + pat = DP_TRAINING_PATTERN_2; + } + + ret = xlnx_dp_set_train_patttern(dp, pat); + if (ret < 0) + return XLNX_DP_TRAIN_FAILURE; + + for (i = 0; i < DP_MAX_TRAINING_TRIES; i++) { + /* + * Obtain the required delay for channel equalization as + * specified by the RX device. + */ + drm_dp_link_train_channel_eq_delay(&dp->aux, dp->dpcd); + + ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); + if (ret < 0) + return XLNX_DP_TRAIN_FAILURE; + + cr_done = drm_dp_clock_recovery_ok(link_status, lane_cnt); + if (!cr_done) + break; + /* + * check if all lanes have accomplished channel equalization, + * symbol lock, and interlane alignment. + */ + ce_done = drm_dp_channel_eq_ok(link_status, lane_cnt); + if (ce_done) + return XLNX_DP_TRAIN_SUCCESS; + + ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); + if (ret < 0) + return XLNX_DP_TRAIN_FAILURE; + + ret = xlnx_dp_tx_adj_vswing_preemp(dp, link_status); + if (ret != 0) + return XLNX_DP_TRAIN_FAILURE; + } + /* + * Tried 5 times with no success. Try a reduced bitrate first, then + * reduce the number of lanes. + */ + + if (!cr_done) { + /* Down link on CR failure in EQ state */ + config->cr_done_oldstate = config->max_lanes; + return XLNX_DP_ADJUST_LINKRATE; + } else if ((mode->lane_cnt == 1) && !ce_done) { + /* Need to set lanecount for next iter */ + mode->lane_cnt = config->max_lanes; + config->cr_done_oldstate = config->max_lanes; + return XLNX_DP_ADJUST_LINKRATE; + } else if ((mode->lane_cnt > 1) && !ce_done) { + /* For EQ failure downlink the lane count */ + return XLNX_DP_ADJUST_LANECOUNT; + } + + config->cr_done_oldstate = config->max_lanes; + + return XLNX_DP_ADJUST_LINKRATE; +} + +/** + * xlnx_dp_run_training - Run the link training process + * @dp: DisplayPort core structure + * + * This function is implemented as a state machine, with each state returning + * the next state. First, the clock recovery sequence will be run; if successful, + * the channel equalization sequence will run. If either the clock recovery or + * channel equalization sequence failed, the link rate or the number of lanes + * used will be reduced and training will be re-attempted. If training fails + * at the minimal data rate, 1.62 Gbps with a single lane, training will no + * longer re-attempt and fail. + * + * Return: 0 if the training process succeeded. + * error value on training failure. + */ +static int xlnx_dp_run_training(struct xlnx_dp *dp) +{ + struct xlnx_dp_link_config *config = &dp->link_config; + enum xlnx_dp_train_state state = XLNX_DP_TRAIN_CR; + int ret; + + while (1) { + switch (state) { + case XLNX_DP_TRAIN_CR: + state = xlnx_dp_link_train_cr(dp); + break; + case XLNX_DP_TRAIN_CE: + state = xlnx_dp_link_train_ce(dp); + break; + case XLNX_DP_ADJUST_LINKRATE: + state = xlnx_dp_adjust_linkrate(dp); + break; + case XLNX_DP_ADJUST_LANECOUNT: + state = xlnx_dp_adjust_lanecount(dp); + break; + default: + break; + } + + if (state == XLNX_DP_TRAIN_SUCCESS) { + config->cr_done_oldstate = config->max_lanes; + config->cr_done_cnt = config->max_lanes; + dev_dbg(dp->dev, "dp training is success !!"); + break; + } else if (state == XLNX_DP_TRAIN_FAILURE) { + config->cr_done_oldstate = config->max_lanes; + config->cr_done_cnt = config->max_lanes; + goto err_out; + } + + if (state == XLNX_DP_ADJUST_LINKRATE || + state == XLNX_DP_ADJUST_LANECOUNT) { + ret = xlnx_dp_set_train_patttern(dp, DP_TRAINING_PATTERN_DISABLE); + if (ret < 0) { + dev_err(dp->dev, + "failed to disable training pattern\n"); + goto err_out; + } + } + } + + return 0; +err_out: + dev_err(dp->dev, "failed to train the DP link\n"); + return -EIO; +} + +static void xlnx_dp_phy_reset(struct xlnx_dp *dp, u32 reset) +{ + u32 phy_val, reg_val; + + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 0); + + /* Preserve the current PHY settings */ + phy_val = xlnx_dp_read(dp->dp_base, XDPTX_PHYCONFIG_REG); + + /* Apply reset */ + reg_val = phy_val | reset; + xlnx_dp_write(dp->dp_base, XDPTX_PHYCONFIG_REG, reg_val); + + /* Remove reset */ + xlnx_dp_write(dp->dp_base, XDPTX_PHYCONFIG_REG, phy_val); + + /* Wait for the PHY to be ready */ + xlnx_dp_phy_ready(dp); + + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 1); +} + +/** + * xlnx_dp_aux_cmd_submit - Submit aux command + * @dp: DisplayPort IP core structure + * @cmd: aux command + * @addr: aux address + * @buf: buffer for command data + * @bytes: number of bytes for @buf + * @reply: reply code to be returned + * + * Submit an aux command. All aux related commands, native or i2c aux + * read/write, are submitted through this function. The function is mapped to + * the transfer function of struct drm_dp_aux. This function involves in + * multiple register reads/writes, thus synchronization is needed, and it is + * done by drm_dp_helper using @hw_mutex. The calling thread goes into sleep + * if there's no immediate reply to the command submission. The reply code is + * returned at @reply if @reply != NULL. + * + * Return: 0 if the command is submitted properly, or corresponding error code: + * -EBUSY when there is any request already being processed + * -ETIMEDOUT when receiving reply is timed out + * -EIO when received bytes are less than requested + */ +static int xlnx_dp_aux_cmd_submit(struct xlnx_dp *dp, u32 cmd, u32 addr, + u8 *buf, u32 bytes, u8 *reply) +{ + bool is_read = (cmd & XDPTX_AUX_READ_BIT) ? true : false; + void __iomem *dp_base = dp->dp_base; + u32 reg, i, bytesleft, address; + u8 *data; + u8 no_of_bytes; + + bytesleft = bytes; + address = addr; + + while (bytesleft > 0) { + reg = xlnx_dp_read(dp_base, XDPTX_INTR_SIGSTATE_REG); + if (reg & XDPTX_INTR_SIGREQSTATE) + return -EBUSY; + + address = addr + (bytes - bytesleft); + xlnx_dp_write(dp_base, XDPTX_AUX_ADDR_REG, address); + + /* Increment the pointer to the supplied data buffer. */ + data = &buf[bytes - bytesleft]; + + if (bytesleft > 16) + no_of_bytes = 16; + else + no_of_bytes = bytesleft; + + bytesleft -= no_of_bytes; + if (!is_read) { + for (i = 0; i < no_of_bytes; i++) { + xlnx_dp_write(dp_base, XDPTX_AUX_WRITEFIFO_REG, + data[i]); + } + } + + reg = cmd << XDPTX_AUXCMD_SHIFT; + if (!bytes) + reg |= XDPTX_AUXCMD_ADDRONLY_MASK; + else + reg |= (no_of_bytes - 1) << XDPTX_AUXCMD_BYTES_SHIFT; + xlnx_dp_write(dp_base, XDPTX_AUXCMD_REG, reg); + + /* Wait for reply to be delivered upto 2ms */ + for (i = 0; ; i++) { + reg = xlnx_dp_read(dp_base, XDPTX_INTR_SIGSTATE_REG); + if (reg & XDPTX_INTR_SIGRPLYSTATE) + break; + + if (reg & XDPTX_INTR_RPLYTIMEOUT || + i == 2) + return -ETIMEDOUT; + + usleep_range(1000, 1100); + } + + reg = xlnx_dp_read(dp_base, XDPTX_AUXREPLY_CODE_REG); + if (reply) + *reply = reg; + + if (is_read && !reg) { + reg = xlnx_dp_read(dp_base, XDPTX_AUXREPLY_DATACNT_REG); + if ((reg & XDPTX_AUXREPLY_DATACNT_MASK) != no_of_bytes) + return -EIO; + + for (i = 0; i < no_of_bytes; i++) { + data[i] = xlnx_dp_read(dp_base, + XDPTX_AUXREPLY_DATA_REG); + } + } + } + + return 0; +} + +static ssize_t +xlnx_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) +{ + struct xlnx_dp *dp = container_of(aux, struct xlnx_dp, aux); + int ret; + unsigned int i, iter; + + /* This is to iterate at least 50 msec */ + iter = 50 * 1000 / 400; + + for (i = 0; i < iter; i++) { + ret = xlnx_dp_aux_cmd_submit(dp, msg->request, msg->address, + msg->buffer, msg->size, + &msg->reply); + if (!ret) { + dev_dbg(dp->dev, "aux %d retries\n", i); + return msg->size; + } + + if (dp->status == connector_status_disconnected) { + dev_info(dp->dev, "no connected aux device\n"); + return -ENODEV; + } + + usleep_range(3200, 3300); + } + + dev_info(dp->dev, "failed aux transfer\n"); + + return ret; +} + +/** + * xlnx_dp_init_aux - Initialize the DP aux + * @dp: DisplayPort IP core structure + * + * Initialize the DP aux. The aux clock is derived from the axi clock, so + * this function gets the axi clock frequency and calculates the filter + * value. Additionally, the interrupts and transmitter are enabled. + * + * Return: 0 on success, error value otherwise + */ +static int xlnx_dp_init_aux(struct xlnx_dp *dp) +{ + unsigned long rate; + u32 reg, w; + + rate = clk_get_rate(dp->axi_lite_clk); + if (rate < XDPTX_CLKDIV_MHZ) { + dev_err(dp->dev, "aclk should be higher than 1MHz\n"); + return -EINVAL; + } + + /* Allowable values for this register are: 8, 16, 24, 32, 40, 48 */ + for (w = 8; w <= 48; w += 8) { + /* AUX pulse width should be between 0.4 to 0.6 usec */ + if (w >= (4 * rate / 10000000) && + w <= (6 * rate / 10000000)) + break; + } + + if (w > 48) + w = 48; + + reg = w << XDPTX_CLKDIV_AUXFILTER_SHIFT; + reg |= rate / XDPTX_CLKDIV_MHZ; + xlnx_dp_write(dp->dp_base, XDPTX_CLKDIV_REG, reg); + + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 1); + return 0; +} + +/** + * xlnx_dp_exit_aux - De-initialize the DP aux + * @dp: DisplayPort IP core structure + * + * De-initialize the DP aux. Disable all interrupts which are enabled + * through aux initialization, as well as the transmitter. + */ +static void xlnx_dp_exit_aux(struct xlnx_dp *dp) +{ + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 0); + xlnx_dp_write(dp->dp_base, XDPTX_INTR_MASK_REG, 0xfff); +} + +/** + * xlnx_dp_update_misc - Write the misc registers + * @dp: DisplayPort IP core structure + * + * The misc register values are stored in the structure, and this + * function applies the values into the registers. + */ +static void xlnx_dp_update_misc(struct xlnx_dp *dp) +{ + struct xlnx_dp_config *config = &dp->config; + + if (!dp->colorimetry_through_vsc) { + xlnx_dp_write(dp->dp_base, XDPTX_MAINSTRM_MISC0_REG, + config->misc0); + xlnx_dp_write(dp->dp_base, XDPTX_MAINSTRM_MISC1_REG, 0x0); + } else { + xlnx_dp_set(dp->dp_base, XDPTX_MAINSTRM_MISC1_REG, + XDPTX_MAINSTRM_MISC1_TIMING_IGNORED_MASK); + } +} + +/** + * xlnx_dp_set_sync_mode - Set the sync mode bit in the software misc state + * @dp: DisplayPort IP core structure + * @mode: flag if the sync mode should be on or off + * + * Set the bit in software misc state. To apply to hardware, + * xlnx_dp_update_misc() should be called. + */ +static void xlnx_dp_set_sync_mode(struct xlnx_dp *dp, bool mode) +{ + struct xlnx_dp_config *config = &dp->config; + + if (mode) + config->misc0 |= XDPTX_MAINSTRM_MISC0_MASK; + else + config->misc0 &= ~XDPTX_MAINSTRM_MISC0_MASK; +} + +static void xlnx_dp_vsc_pkt_handler(struct xlnx_dp *dp) +{ + struct xlnx_dp_vscpkt *vscpkt = &dp->vscpkt; + int i; + + if (dp->colorimetry_through_vsc) { + xlnx_dp_write(dp->dp_base, XDPTX_AUDIO_EXT_DATA(1), + vscpkt->header); + for (i = 0; i < XDPTX_AUDIO_EXT_DATA_2ND_TO_9TH_WORD; i++) { + xlnx_dp_write(dp->dp_base, XDPTX_AUDIO_EXT_DATA(i + 2), + vscpkt->payload[i]); + } + } +} + +static void xlnx_dp_prepare_vsc(struct xlnx_dp *dp) +{ + struct xlnx_dp_config *config = &dp->config; + struct xlnx_dp_vscpkt *vscpkt = &dp->vscpkt; + int i; + u32 payload_data = 0, bpc; + + vscpkt->header = XDPTX_VSC_SDP_PIXELENC_HEADER_MASK; + payload_data |= config->fmt << XDPTX_VSC_SDP_FMT_SHIFT; + + switch (config->bpc) { + case 6: + bpc = 0x0; + break; + case 8: + bpc = 0x1; + break; + case 10: + bpc = 0x2; + break; + case 12: + bpc = 0x3; + break; + case 16: + bpc = 0x4; + break; + default: + dev_err(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n", + config->bpc); + bpc = 0x0; + } + + bpc &= XDPTX_VSC_SDP_BPC_MASK; + payload_data |= (bpc << XDPTX_VSC_SDP_BPC_SHIFT); + /* TODO: it has to be dynamic */ + payload_data |= (0x1 << XDPTX_VSC_SDP_DYNAMIC_RANGE_SHIFT); + + dev_dbg(dp->dev, "payload_data 0x%x", payload_data); + + /* population vsc payload */ + for (i = 0; i < 8; i++) { + if (i == 4) { + vscpkt->payload[i] = payload_data; + continue; + } + vscpkt->payload[i] = 0x0; + } +} + +/** + * xlnx_dp_set_bpc - Set bpc value in software misc state + * @dp: DisplayPort IP core structure + * @bpc: bits per component + * + * Return: 0 on success, or the fallback bpc value + */ +static u32 xlnx_dp_set_bpc(struct xlnx_dp *dp, u8 bpc) +{ + struct xlnx_dp_config *config = &dp->config; + unsigned int ret = 0; + + if (dp->connector.display_info.bpc && + dp->connector.display_info.bpc != bpc) { + dev_err(dp->dev, "requested bpc (%u) != display info (%u)\n", + bpc, dp->connector.display_info.bpc); + bpc = dp->connector.display_info.bpc; + } + + config->misc0 &= ~XDPTX_MISC0_BPC_MASK; + switch (bpc) { + case 6: + config->misc0 |= XDPTX_MISC0_BPC6_MASK; + break; + case 8: + config->misc0 |= XDPTX_MISC0_BPC8_MASK; + break; + case 10: + config->misc0 |= XDPTX_MISC0_BPC10_MASK; + break; + case 12: + config->misc0 |= XDPTX_MISC0_BPC12_MASK; + break; + case 16: + config->misc0 |= XDPTX_MISC0_BPC16_MASK; + break; + default: + dev_err(dp->dev, "Not supported bpc (%u). fall back to 8bpc\n", + bpc); + config->misc0 |= XDPTX_MISC0_BPC8_MASK; + ret = 8; + } + config->bpc = bpc; + xlnx_dp_update_bpp(dp); + + return ret; +} + +/** + * xlnx_dp_encoder_mode_set_transfer_unit - Set the transfer unit values + * @dp: DisplayPort IP core structure + * @mode: requested display mode + * + * Set the transfer unit, and calculate all transfer unit size related values. + * Calculation is based on DP and IP core specification. + */ +static void +xlnx_dp_encoder_mode_set_transfer_unit(struct xlnx_dp *dp, + struct drm_display_mode *mode) +{ + struct xlnx_dp_config *config = &dp->config; + u32 tu = XDPTX_DEF_TRANSFER_UNITSIZE, temp; + u32 bw, vid_kbytes, avg_bytes_per_tu, init_wait, min_bytes_per_tu; + + /* Use the max transfer unit size (default) */ + xlnx_dp_write(dp->dp_base, XDPTX_TRANSFER_UNITSIZE_REG, tu); + + vid_kbytes = (mode->clock / 1000) * (dp->config.bpp / 8); + bw = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); + avg_bytes_per_tu = vid_kbytes * tu / (dp->mode.lane_cnt * bw); + min_bytes_per_tu = avg_bytes_per_tu / 1000; + xlnx_dp_write(dp->dp_base, XDPTX_MINBYTES_PERTU_REG, + min_bytes_per_tu); + + temp = (avg_bytes_per_tu % 1000) * 1024 / 1000; + xlnx_dp_write(dp->dp_base, XDPTX_FRACBYTES_PERTU_REG, temp); + + init_wait = tu - min_bytes_per_tu; + + /* Configure the initial wait cycle based on transfer unit size */ + if (min_bytes_per_tu <= 4) + init_wait = tu; + else if ((config->misc0 & XDPTX_MISC0_YCRCB422_MASK) == + XDPTX_MISC0_YCRCB422_MASK) + init_wait = init_wait / 2; + + xlnx_dp_write(dp->dp_base, XDPTX_INIT_WAIT_REG, init_wait); +} + +/** + * xlnx_dp_encoder_mode_set_stream - Configure the main stream + * @dp: DisplayPort IP core structure + * @mode: requested display mode + * + * Configure the main stream based on the requested mode @mode. Calculation is + * based on IP core specification. + */ +static void xlnx_dp_encoder_mode_set_stream(struct xlnx_dp *dp, + struct drm_display_mode *mode) +{ + void __iomem *dp_base = dp->dp_base; + u32 reg, wpl, ppc; + u8 lane_cnt = dp->mode.lane_cnt; + + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_HTOTAL_REG, mode->htotal); + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_VTOTAL_REG, mode->vtotal); + + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_POL_REG, + (!!(mode->flags & DRM_MODE_FLAG_PVSYNC) << + XDPTX_MAINSTRM_POLVSYNC_SHIFT) | + (!!(mode->flags & DRM_MODE_FLAG_PHSYNC) << + XDPTX_MAINSTRM_POLHSYNC_SHIFT)); + + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_HSWIDTH_REG, + mode->hsync_end - mode->hsync_start); + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_VSWIDTH_REG, + mode->vsync_end - mode->vsync_start); + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_HRES_REG, mode->hdisplay); + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_VRES_REG, mode->vdisplay); + + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_HSTART_REG, + mode->htotal - mode->hsync_start); + xlnx_dp_write(dp_base, XDPTX_MAINSTRM_VSTART_REG, + mode->vtotal - mode->vsync_start); + xlnx_dp_update_misc(dp); + + if (mode->clock > 530000) + ppc = 4; + else if (mode->clock > 270000) + ppc = 2; + else + ppc = 1; + + xlnx_dp_write(dp_base, XDPTX_USER_PIXELWIDTH_REG, ppc); + dp->config.ppc = ppc; + + xlnx_dp_write(dp_base, XDPTX_M_VID_REG, mode->clock); + reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); + xlnx_dp_write(dp_base, XDPTX_N_VID_REG, reg); + + /* In synchronous mode, set the dividers */ + if (dp->config.misc0 & XDPTX_MAINSTRM_MISC0_MASK) { + reg = drm_dp_bw_code_to_link_rate(dp->mode.bw_code); + xlnx_dp_write(dp_base, XDPTX_N_VID_REG, reg); + xlnx_dp_write(dp_base, XDPTX_M_VID_REG, mode->clock); + } + + wpl = (mode->hdisplay * dp->config.bpp + 15) / 16; + reg = wpl + wpl % lane_cnt - lane_cnt; + xlnx_dp_write(dp_base, XDPTX_USER_DATACNTPERLANE_REG, reg); +} + +static void xlnx_dp_mainlink_en(struct xlnx_dp *dp, u8 enable) +{ + xlnx_dp_write(dp->dp_base, XDPTX_SCRAMBLER_RESET, + XDPTX_SCRAMBLER_RESET_MASK); + xlnx_dp_write(dp->dp_base, XDPTX_MAINSTRM_ENABLE_REG, enable); +} + +static int xlnx_dp_power_cycle(struct xlnx_dp *dp) +{ + int ret = 0, i; + u8 value; + + /* sink Power cycle */ + for (i = 0; i < XDPTX_SINK_PWR_CYCLES; i++) { + ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value); + + value &= ~DP_SET_POWER_MASK; + value |= DP_SET_POWER_D3; + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); + + usleep_range(300, 400); + value &= ~DP_SET_POWER_MASK; + value |= DP_SET_POWER_D0; + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); + usleep_range(300, 400); + ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value); + if (ret == 1) + break; + usleep_range(3000, 4000); + } + + if (ret < 0) { + dev_err(dp->dev, "DP aux failed\n"); + return ret; + } + + return 0; +} + +/** + * xlnx_dp_start - start the DisplayPort core + * @dp: DisplayPort IP core structure + * + * This function trains the DisplayPort link based on the sink capabilities and + * enables the main link. + */ +static void xlnx_dp_start(struct xlnx_dp *dp) +{ + struct xlnx_dp_mode *mode = &dp->mode; + struct xlnx_hdcptx *dptxhdcp = &dp->tx_hdcp; + int link_rate = dp->link_config.link_rate; + int ret = 0; + u32 val, intr_mask; + u8 data; + bool enhanced; + + mode->bw_code = drm_dp_link_rate_to_bw_code(link_rate); + mode->lane_cnt = dp->link_config.lane_count; + dp->link_config.cr_done_oldstate = dp->link_config.max_lanes; + + xlnx_dp_init_aux(dp); + if (dp->status != connector_status_connected) { + dev_info(dp->dev, "Display not connected\n"); + return; + } + + xlnx_dp_power_cycle(dp); + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 0); + /* + * Give a bit of time for DP IP after monitor came up and starting + * link training + */ + msleep(100); + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 1); + + ret = xlnx_dp_set_linkrate(dp, mode->bw_code); + if (ret < 0) { + dev_err(dp->dev, "failed to set link rate\n"); + return; + } + + ret = xlnx_dp_set_lanecount(dp, mode->lane_cnt); + if (ret < 0) { + dev_err(dp->dev, "failed to set lane count\n"); + return; + } + + /* Disable MST mode in both the RX and TX */ + ret = drm_dp_dpcd_writeb(&dp->aux, DP_MSTM_CTRL, 0); + if (ret < 0) { + dev_dbg(dp->dev, "DPCD write failed"); + return; + } + xlnx_dp_write(dp->dp_base, XDPTX_MST_CONFIG, 0x0); + + /* Disable main link during training. */ + val = xlnx_dp_read(dp->dp_base, XDPTX_MAINSTRM_ENABLE_REG); + if (val) + xlnx_dp_mainlink_en(dp, 0x0); + + /* Disable HPD pulse interrupts during link training */ + intr_mask = xlnx_dp_read(dp->dp_base, XDPTX_INTR_MASK_REG); + xlnx_dp_write(dp->dp_base, XDPTX_INTR_MASK_REG, + intr_mask | XDPTX_INTR_HPDPULSE_MASK); + + /* Enable clock spreading for both DP TX and RX device */ + drm_dp_dpcd_readb(&dp->aux, DP_DOWNSPREAD_CTRL, &data); + if (dp->dpcd[DP_MAX_DOWNSPREAD] & 0x1) { + xlnx_dp_write(dp->dp_base, XDPTX_DOWNSPREAD_CTL_REG, 1); + data |= XDPTX_DPCD_SPREAD_AMP_MASK; + } else { + xlnx_dp_write(dp->dp_base, XDPTX_DOWNSPREAD_CTL_REG, 0); + data &= ~XDPTX_DPCD_SPREAD_AMP_MASK; + } + drm_dp_dpcd_writeb(&dp->aux, DP_DOWNSPREAD_CTRL, data); + + /* Enahanced framing model */ + drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); + enhanced = drm_dp_enhanced_frame_cap(dp->dpcd); + if (enhanced) { + xlnx_dp_write(dp->dp_base, XDPTX_EFRAME_EN_REG, 1); + data |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + } + + ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, data); + if (ret < 0) { + dev_err(dp->dev, "failed to set lane count\n"); + return; + } + /* set channel encoding */ + ret = drm_dp_dpcd_writeb(&dp->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, + DP_SET_ANSI_8B10B); + if (ret < 0) { + dev_err(dp->dev, "failed to set ANSI 8B/10B encoding\n"); + return; + } + /* Reset PHY */ + xlnx_dp_phy_reset(dp, XDPTX_PHYCONFIG_RESET_MASK); + + /* Wait for PHY ready */ + ret = xlnx_dp_phy_ready(dp); + if (ret < 0) + return; + + memset(dp->train_set, 0, XDPTX_MAX_LANES); + + ret = xlnx_dp_run_training(dp); + if (ret < 0) { + dev_err(dp->dev, "DP Link Training Failed\n"); + return; + } + + ret = xlnx_dp_post_training(dp); + if (ret < 0) { + dev_err(dp->dev, "failed post trining settings\n"); + return; + } + + /* re-enable main link after training if required */ + if (val) + xlnx_dp_mainlink_en(dp, 0x1); + /* Enable HDP interrupts after link training */ + xlnx_dp_write(dp->dp_base, XDPTX_INTR_MASK_REG, intr_mask); + + dev_dbg(dp->dev, "Training done:"); + + /* reset the transmitter */ + xlnx_dp_write(dp->dp_base, XDPTX_SOFT_RST, + XDPTX_SOFT_RST_VIDEO_STREAM_ALL_MASK | + XDPTX_SOFT_RST_HDCP_MASK); + xlnx_dp_write(dp->dp_base, XDPTX_SOFT_RST, 0x0); + + /* Enable VTC and MainStream */ + xlnx_dp_set(dp->dp_base, dp->vtc_off + XDPTX_VTC_CTL, + XDPTX_VTC_CTL_GE); + xlnx_dp_mainlink_en(dp, 0x1); + + ret = xlnx_dp_check_link_status(dp); + if (ret < 0) { + dev_err(dp->dev, "Link is DOWN after main link enabled!\n"); + return; + } + if (dp->config.hdcp2x_enable || dp->config.hdcp1x_enable) { + if (dp->config.hdcp2x_enable) { + xlnx_dp_set(dp->dp_base, XDP_TX_HDCP2x_ENABLE, + XDP_TX_HDCP2x_ENABLE_BYPASS_DISABLE_MASK); + } + if (dp->config.hdcp1x_enable) { + val = xlnx_dp_read(dp->dp_base, XDP_TX_HDCP1X_ENABLE); + val |= XDP_TX_HDCP1X_ENABLE_BYPASS_DISABLE_MASK; + xlnx_dp_write(dp->dp_base, XDP_TX_HDCP1X_ENABLE, val); + } + ret = xlnx_start_hdcp_engine(dptxhdcp, mode->lane_cnt); + if (ret < 0) { + dev_err(dp->dev, "Failed to Start HDCP\n"); + return; + } + } + + if (dp->colorimetry_through_vsc) { + /* program the VSC extended packet */ + xlnx_dp_vsc_pkt_handler(dp); + /* This ensures that VSC pkt is sent every frame */ + xlnx_dp_set(dp->dp_base, XDPTX_MAINSTRM_MISC0_REG, + XDPTX_MAINSTRM_MISC0_EXT_VSYNC_MASK); + } + /* enable audio */ + xlnx_dp_set(dp->dp_base, XDPTX_AUDIO_CTRL_REG, 0x1); + /* Enabling TX interrupts */ + xlnx_dp_write(dp->dp_base, XDPTX_INTR_MASK_REG, 0); +} + +/** + * xlnx_dp_hdcp_reset - Reset HDCP module + * @dp: DisplayPort IP core structure + * + * This function resets HDCP cipher engine, + * protocol state machine and its internal parameters. + * + * Return: 0 on success, or the error code returned + * from the callee functions. + */ +static int xlnx_dp_hdcp_reset(struct xlnx_dp *dp) +{ + struct xlnx_hdcptx *dptxhdcp = &dp->tx_hdcp; + int ret; + + cancel_delayed_work(&dp->hdcp_cp_irq_work); + ret = xlnx_hdcp_tx_reset(dptxhdcp); + if (ret < 0) { + dev_dbg(dp->dev, "failed to reset HDCP Cipher Engine"); + return ret; + } + + return 0; +} + +/** + * xlnx_dp_stop - stop the DisplayPort core + * @dp: DisplayPort IP core structure + * + * This function disables the DisplayPort main link and VTC. + */ +static void xlnx_dp_stop(struct xlnx_dp *dp) +{ + struct phy_configure_opts_dp *phy_cfg = &dp->phy_opts.dp; + + xlnx_dp_write(dp->dp_base, XDPTX_MAINSTRM_ENABLE_REG, 0); + + /* Disabling the audio in dp core */ + xlnx_dp_clr(dp->dp_base, XDPTX_AUDIO_CTRL_REG, 0); + + /* set Vs and Pe to 0, 0 on cable disconnect */ + phy_cfg->pre[0] = 0; + phy_cfg->voltage[0] = 0; + phy_cfg->set_voltages = 1; + + if (!dp->config.versal_gt_present) + phy_configure(dp->phy[0], &dp->phy_opts); + else + xlnx_dp_tx_pe_vs_adjust_handler(dp, &dp->phy_opts.dp); + + /* Disable VTC */ + xlnx_dp_clr(dp->dp_base, dp->vtc_off + XDPTX_VTC_CTL, + XDPTX_VTC_CTL_GE); + /* Reset HDCP Engine. */ + if (dp->config.hdcp2x_enable || dp->config.hdcp1x_enable) + xlnx_dp_hdcp_reset(dp); +} + +static int xlnx_dp_txconnected(struct xlnx_dp *dp) +{ + u32 status; + u8 retries = 0; + + do { + status = xlnx_dp_read(dp->dp_base, + XDPTX_INTR_SIGSTATE_REG) & 0x1; + if (retries > 5) + return false; + retries++; + usleep_range(1000, 1100); + } while (status == 0); + + return true; +} + +/* + * DRM connector functions + */ +static enum drm_connector_status +xlnx_dp_connector_detect(struct drm_connector *connector, bool force) +{ + struct xlnx_dp *dp = connector_to_dp(connector); + struct xlnx_dp_link_config *link_config = &dp->link_config; + struct xlnx_dp_mode *mode = &dp->mode; + int ret; + u8 dpcd_ext[DP_RECEIVER_CAP_SIZE]; + u8 max_link_rate, ext_cap_rd = 0, data; + + if (!xlnx_dp_txconnected(dp)) { + dev_dbg(dp->dev, "Display is not connected"); + goto disconnected; + } + + /* Reading the Ext capability for compliance */ + ret = drm_dp_dpcd_read(&dp->aux, DP_DP13_DPCD_REV, dpcd_ext, + sizeof(dpcd_ext)); + if ((dp->dpcd[6] & 0x1) == 0x1) { + ret = drm_dp_dpcd_read(&dp->aux, DP_DOWNSTREAM_PORT_0, + dpcd_ext, sizeof(dpcd_ext)); + } + + ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd, + sizeof(dp->dpcd)); + if (ret < 0) { + dev_dbg(dp->dev, "DPCD read first try fails"); + ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd, + sizeof(dp->dpcd)); + if (ret < 0) { + dev_info(dp->dev, "DPCD read failes"); + goto disconnected; + } + } + /* set MaxLinkRate to TX rate, if sink provides a non-standard value */ + if (dp->dpcd[DP_MAX_LINK_RATE] != DP_LINK_BW_8_1 && + dp->dpcd[DP_MAX_LINK_RATE] != DP_LINK_BW_5_4 && + dp->dpcd[DP_MAX_LINK_RATE] != DP_LINK_BW_2_7 && + dp->dpcd[DP_MAX_LINK_RATE] != DP_LINK_BW_1_62) { + dp->dpcd[DP_MAX_LINK_RATE] = DP_LINK_BW_8_1; + } + + if (dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] & + DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT) { + ret = drm_dp_dpcd_read(&dp->aux, DP_DP13_MAX_LINK_RATE, + &max_link_rate, 1); + if (ret < 0) { + dev_dbg(dp->dev, "DPCD read failed"); + goto disconnected; + } + + if (max_link_rate == DP_LINK_BW_8_1) + dp->dpcd[DP_MAX_LINK_RATE] = DP_LINK_BW_8_1; + + /* compliance: UCD400 required reading these extended registers */ + ret = drm_dp_dpcd_read(&dp->aux, DP_DP13_MAX_LINK_RATE, + &ext_cap_rd, 1); + ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT_ESI, + &ext_cap_rd, 1); + ret = drm_dp_dpcd_read(&dp->aux, + DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, + &ext_cap_rd, 1); + ret = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS_ESI, + &ext_cap_rd, 1); + ret = drm_dp_dpcd_read(&dp->aux, DP_LANE2_3_STATUS_ESI, + &ext_cap_rd, 1); + ret = drm_dp_dpcd_read(&dp->aux, + DP_LANE_ALIGN_STATUS_UPDATED_ESI, + &ext_cap_rd, 1); + ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_STATUS_ESI, + &ext_cap_rd, 1); + if (ret < 0) + dev_dbg(dp->dev, "DPCD read fails"); + } + + link_config->max_rate = min_t(int, + drm_dp_max_link_rate(dp->dpcd), + dp->config.max_link_rate); + link_config->max_lanes = min_t(u8, + drm_dp_max_lane_count(dp->dpcd), + dp->config.max_lanes); + link_config->link_rate = link_config->max_rate; + link_config->lane_count = link_config->max_lanes; + mode->lane_cnt = link_config->max_lanes; + mode->bw_code = drm_dp_link_rate_to_bw_code(link_config->link_rate); + + ret = drm_dp_dpcd_readb(&dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST, + &data); + if (ret < 0) { + dev_dbg(dp->dev, "DPCD read failed"); + goto disconnected; + } + dp->status = connector_status_connected; + + if (data & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED) + dp->colorimetry_through_vsc = true; + else + dp->colorimetry_through_vsc = false; + + if (dp->enabled) { + xlnx_dp_stop(dp); + xlnx_dp_start(dp); + } + + return connector_status_connected; +disconnected: + dp->status = connector_status_disconnected; + if (dp->enabled) + xlnx_dp_stop(dp); + + return connector_status_disconnected; +} + +static int xlnx_dp_connector_get_modes(struct drm_connector *connector) +{ + struct xlnx_dp *dp = connector_to_dp(connector); + struct edid *edid; + int ret; + + edid = drm_get_edid(connector, &dp->aux.ddc); + if (!edid) { + drm_connector_update_edid_property(connector, NULL); + dp->have_edid = false; + return 0; + } + + drm_connector_update_edid_property(connector, edid); + ret = drm_add_edid_modes(connector, edid); + dp->have_edid = true; + kfree(edid); + + return ret; +} + +static struct drm_encoder * +xlnx_dp_connector_best_encoder(struct drm_connector *connector) +{ + struct xlnx_dp *dp = connector_to_dp(connector); + + return &dp->encoder; +} + +static int xlnx_dp_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct xlnx_dp *dp = connector_to_dp(connector); + u8 max_lanes = dp->link_config.max_lanes; + u8 bpp = dp->config.bpp; + int max_rate = dp->link_config.max_rate; + int rate; + + if (mode->clock > XDPTX_MAX_FREQ) { + dev_info(dp->dev, "filtered the mode, %s,for high pixel rate\n", + mode->name); + drm_mode_debug_printmodeline(mode); + return MODE_CLOCK_HIGH; + } + + /* check with link rate and lane count */ + rate = XDPTX_MAX_RATE(max_rate, max_lanes, bpp); + if (mode->clock > rate) { + dev_dbg(dp->dev, "filtered the mode, %s,for high pixel rate\n", + mode->name); + drm_mode_debug_printmodeline(mode); + + return MODE_CLOCK_HIGH; + } + + return MODE_OK; +} + +static void xlnx_dp_connector_destroy(struct drm_connector *connector) +{ + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static int +xlnx_dp_connector_atomic_set_property(struct drm_connector *connector, + struct drm_connector_state *state, + struct drm_property *property, + uint64_t val) +{ + struct xlnx_dp *dp = connector_to_dp(connector); + unsigned int bpc; + + if (property == dp->sync_prop) { + xlnx_dp_set_sync_mode(dp, val); + } else if (property == dp->bpc_prop) { + bpc = xlnx_dp_set_bpc(dp, val); + if (bpc) { + drm_object_property_set_value(&connector->base, + property, bpc); + return -EINVAL; + } + } else { + return -EINVAL; + } + + return 0; +} + +static int +xlnx_dp_connector_atomic_get_property(struct drm_connector *connector, + const struct drm_connector_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct xlnx_dp *dp = connector_to_dp(connector); + + if (property == dp->sync_prop) + *val = (dp->config.misc0 & XDPTX_MAINSTRM_MISC0_MASK); + else if (property == dp->bpc_prop) + *val = dp->config.bpc; + else + return -EINVAL; + + return 0; +} + +static const struct drm_connector_funcs xlnx_dp_connector_funcs = { + .detect = xlnx_dp_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = xlnx_dp_connector_destroy, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .reset = drm_atomic_helper_connector_reset, + .atomic_set_property = xlnx_dp_connector_atomic_set_property, + .atomic_get_property = xlnx_dp_connector_atomic_get_property, +}; + +static struct drm_connector_helper_funcs xlnx_dp_connector_helper_funcs = { + .get_modes = xlnx_dp_connector_get_modes, + .best_encoder = xlnx_dp_connector_best_encoder, + .mode_valid = xlnx_dp_connector_mode_valid, +}; + +static int xlnx_dp_get_eld(struct device *dev, u8 *buf, size_t len) +{ + struct xlnx_dp *dp = dev_get_drvdata(dev); + size_t size; + + if (!dp->have_edid) + return -EIO; + + size = drm_eld_size(dp->connector.eld); + if (!size) + return -EINVAL; + + if (len < size) + size = len; + memcpy(buf, dp->connector.eld, size); + + return 0; +} + +static unsigned long dp_codec_spk_mask_from_alloc(int spk_alloc) +{ + int i; + static const unsigned long dp_codec_eld_spk_alloc_bits[] = { + [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR, + [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC, + }; + unsigned long spk_mask = 0; + + for (i = 0; i < ARRAY_SIZE(dp_codec_eld_spk_alloc_bits); i++) { + if (spk_alloc & (1 << i)) + spk_mask |= dp_codec_eld_spk_alloc_bits[i]; + } + + return spk_mask; +} + +static int dp_codec_get_ch_alloc_table_idx(u8 *eld, u8 channels) +{ + int i; + u8 spk_alloc; + unsigned long spk_mask; + const struct dp_codec_cea_spk_alloc *cap = dp_codec_channel_alloc; + + spk_alloc = drm_eld_get_spk_alloc(eld); + spk_mask = dp_codec_spk_mask_from_alloc(spk_alloc); + + for (i = 0; i < ARRAY_SIZE(dp_codec_channel_alloc); i++, cap++) { + /* If spk_alloc == 0, DP is unplugged return stereo config */ + if (!spk_alloc && cap->ca_id == 0) + return i; + if (cap->n_ch != channels) + continue; + if (!(cap->mask == (spk_mask & cap->mask))) + continue; + return i; + } + + return -EINVAL; +} + +static int dp_codec_fill_cea_params(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai, + unsigned int channels, + struct hdmi_audio_infoframe *cea) +{ + int idx; + int ret; + u8 eld[MAX_ELD_BYTES]; + + ret = xlnx_dp_get_eld(dai->dev, eld, sizeof(eld)); + if (ret) + return ret; + + ret = snd_pcm_hw_constraint_eld(substream->runtime, eld); + if (ret) + return ret; + + /* Select a channel allocation that matches with ELD and pcm channels */ + idx = dp_codec_get_ch_alloc_table_idx(eld, channels); + if (idx < 0) { + dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", + idx); + return idx; + } + + hdmi_audio_infoframe_init(cea); + cea->channels = channels; + cea->coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; + cea->sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + cea->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; + cea->channel_allocation = dp_codec_channel_alloc[idx].ca_id; + + return 0; +} + +/** + * xlnx_tx_pcm_startup - initialize audio during audio usecase + * @substream: PCM substream + * @dai: runtime dai data + * + * This function is called by ALSA framework before audio + * playback begins. This callback initializes audio. + * + * Return: 0 on success + */ +static int xlnx_tx_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct xlnx_dp *dp = dev_get_drvdata(dai->dev); + + /* Enabling the audio in dp core */ + xlnx_dp_clr(dp->dp_base, XDPTX_AUDIO_CTRL_REG, XDPTX_AUDIO_EN_MASK); + + xlnx_dp_set(dp->dp_base, XDPTX_AUDIO_CTRL_REG, XDPTX_AUDIO_EN_MASK); + + return 0; +} + +/** + * xlnx_tx_pcm_hw_params - sets the playback stream properties + * @substream: PCM substream + * @params: PCM stream hardware parameters + * @dai: runtime dai data + * + * This function is called by ALSA framework after startup callback + * packs the audio infoframe from stream paremters and programs ACR + * block + * + * Return: 0 on success + */ +static int xlnx_tx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct hdmi_audio_infoframe infoframe; + struct xlnx_dp *dp = dev_get_drvdata(dai->dev); + int ret; + u8 infopckt[DP_INFOFRAME_SIZE(AUDIO)] = {0}; + u8 *ptr = (u8 *)dp->tx_audio_data->buffer; + + ret = dp_codec_fill_cea_params(substream, dai, + params_channels(params), + &infoframe); + if (ret < 0) + return ret; + + /* Setting audio channels */ + xlnx_dp_write(dp->dp_base, XDPTX_AUDIO_CHANNELS_REG, + infoframe.channels - 1); + + hdmi_audio_infoframe_pack(&infoframe, infopckt, + DP_INFOFRAME_SIZE(AUDIO)); + /* Setting audio infoframe packet header. Please refer to PG 299 */ + ptr[0] = 0x00; + ptr[1] = 0x84; + ptr[2] = 0x1B; + ptr[3] = 0x44; + memcpy((void *)(&ptr[4]), (void *)(&infopckt[4]), + (DP_INFOFRAME_SIZE(AUDIO) - DP_INFOFRAME_HEADER_SIZE)); + + return 0; +} + +/** + * xlnx_tx_pcm_shutdown - Deinitialze audio when audio usecase is stopped + * @substream: PCM substream + * @dai: runtime dai data + * + * This function is called by ALSA framework before audio playback usecase + * ends. + */ +static void xlnx_tx_pcm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct xlnx_dp *dp = dev_get_drvdata(dai->dev); + + /* Disabling the audio in dp core */ + xlnx_dp_clr(dp->dp_base, XDPTX_AUDIO_CTRL_REG, XDPTX_AUDIO_EN_MASK); +} + +/** + * xlnx_tx_pcm_digital_mute - mute or unmute audio + * @dai: runtime dai data + * @enable: enable or disable mute + * @direction: direction to enable mute (capture/playback) + * + * This function is called by ALSA framework before audio usecase + * starts and before audio usecase ends + * + * Return: 0 on success + */ +static int xlnx_tx_pcm_digital_mute(struct snd_soc_dai *dai, int enable, + int direction) +{ + struct xlnx_dp *dp = dev_get_drvdata(dai->dev); + + if (enable) + xlnx_dp_set(dp->dp_base, XDPTX_AUDIO_CTRL_REG, XDPTX_AUDIO_MUTE_MASK); + else + xlnx_dp_clr(dp->dp_base, XDPTX_AUDIO_CTRL_REG, XDPTX_AUDIO_MUTE_MASK); + + return 0; +} + +static const struct snd_soc_dai_ops xlnx_dp_tx_dai_ops = { + .startup = xlnx_tx_pcm_startup, + .hw_params = xlnx_tx_pcm_hw_params, + .shutdown = xlnx_tx_pcm_shutdown, + .mute_stream = xlnx_tx_pcm_digital_mute, + .no_capture_mute = 1, +}; + +static struct snd_soc_dai_driver xlnx_dp_tx_dai = { + .name = "xlnx_dp_tx", + .playback = { + .stream_name = "I2S Playback", + .channels_min = 2, + .channels_max = 8, + .rates = DP_RATES, + .formats = I2S_FORMATS, + .sig_bits = 24, + }, + .ops = &xlnx_dp_tx_dai_ops, +}; + +static int xlnx_tx_codec_probe(struct snd_soc_component *component) +{ + return 0; +} + +static void xlnx_tx_codec_remove(struct snd_soc_component *component) +{ +} + +static const struct snd_soc_component_driver xlnx_dp_component = { + .probe = xlnx_tx_codec_probe, + .remove = xlnx_tx_codec_remove, +}; + +static int dptx_register_aud_dev(struct device *dev) +{ + return devm_snd_soc_register_component(dev, &xlnx_dp_component, + &xlnx_dp_tx_dai, 1); +} + +static void xlnx_dp_encoder_enable(struct drm_encoder *encoder) +{ + struct xlnx_dp *dp = encoder_to_dp(encoder); + + pm_runtime_get_sync(dp->dev); + + if (!dp->enabled) { + dp->enabled = true; + xlnx_dp_start(dp); + } +} + +static void xlnx_dp_encoder_disable(struct drm_encoder *encoder) +{ + struct xlnx_dp *dp = encoder_to_dp(encoder); + + if (dp->enabled) { + dp->enabled = false; + cancel_delayed_work(&dp->hpd_work); + cancel_delayed_work(&dp->hpd_pulse_work); + xlnx_dp_stop(dp); + } + pm_runtime_put_sync(dp->dev); +} + +static void +xlnx_dp_encoder_atomic_mode_set(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *connector_state) +{ + struct xlnx_dp *dp = encoder_to_dp(encoder); + struct drm_display_mode *mode = &crtc_state->mode; + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + int rate, max_rate = dp->link_config.max_rate; + u32 clock, drm_fourcc; + u8 max_lanes = dp->link_config.max_lanes; + u8 bpp = dp->config.bpp; + + /* + * This assumes that there is no conversion between framebuffer + * and DP Tx + */ + drm_fourcc = encoder->crtc->primary->state->fb->format->format; + + xlnx_dp_set_color(dp, drm_fourcc); + + rate = XDPTX_MAX_RATE(max_rate, max_lanes, bpp); + if (mode->clock > rate) { + dev_err(dp->dev, "the mode, %s,has too high pixel rate\n", + mode->name); + drm_mode_debug_printmodeline(mode); + } + + /* The timing register should be programmed always */ + xlnx_dp_encoder_mode_set_stream(dp, adjusted_mode); + xlnx_dp_encoder_mode_set_transfer_unit(dp, adjusted_mode); + clock = adjusted_mode->clock * 1000; + clk_set_rate(dp->tx_vid_clk, clock / dp->config.ppc); + + xlnx_dp_vtc_set_timing(dp, adjusted_mode); + /* prepare a vsc packet */ + xlnx_dp_prepare_vsc(dp); +} + +static const struct drm_encoder_funcs xlnx_dp_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static const struct drm_encoder_helper_funcs xlnx_dp_encoder_helper_funcs = { + .enable = xlnx_dp_encoder_enable, + .disable = xlnx_dp_encoder_disable, + .atomic_mode_set = xlnx_dp_encoder_atomic_mode_set, +}; + +static void xlnx_dp_hpd_work_func(struct work_struct *work) +{ + struct xlnx_dp *dp; + + dp = container_of(work, struct xlnx_dp, hpd_work.work); + + if (dp->drm) + drm_helper_hpd_irq_event(dp->drm); +} + +/** + * xlnx_dp_hdcp_cp_irq_func - Checks for HDCP information + * whenever CP IRQ is detected. HDCP transmitters must process this interrupt when + * they are received from receivers/repeaters. + * @work: work structure + * + * This function checks for HDCP authentication information via rxstatus register + * as soon as interrupt triggers. + */ +static void xlnx_dp_hdcp_cp_irq_func(struct work_struct *work) +{ + struct xlnx_dp *dp; + struct xlnx_hdcptx *dptxhdcp; + + dp = container_of(work, struct xlnx_dp, hdcp_cp_irq_work.work); + dptxhdcp = &dp->tx_hdcp; + + xlnx_hdcp_tx_process_cp_irq(dptxhdcp); +} + +static struct drm_prop_enum_list xlnx_dp_bpc_enum[] = { + { 6, "6BPC" }, + { 8, "8BPC" }, + { 10, "10BPC" }, + { 12, "12BPC" }, +}; + +static int xlnx_dp_bind(struct device *dev, struct device *master, void *data) +{ + struct xlnx_dp *dp = dev_get_drvdata(dev); + struct drm_encoder *encoder = &dp->encoder; + struct drm_connector *connector = &dp->connector; + struct drm_device *drm = data; + unsigned int ret; + + encoder->possible_crtcs = 1; + drm_encoder_init(drm, encoder, &xlnx_dp_encoder_funcs, + DRM_MODE_ENCODER_TMDS, NULL); + drm_encoder_helper_add(encoder, &xlnx_dp_encoder_helper_funcs); + + connector->polled = DRM_CONNECTOR_POLL_HPD; + ret = drm_connector_init(encoder->dev, connector, + &xlnx_dp_connector_funcs, + DRM_MODE_CONNECTOR_DisplayPort); + if (ret) { + dev_err(dp->dev, "failed to initialize the drm connector"); + goto error_encoder; + } + + drm_connector_helper_add(connector, &xlnx_dp_connector_helper_funcs); + drm_connector_register(connector); + drm_connector_attach_encoder(connector, encoder); + connector->dpms = DRM_MODE_DPMS_OFF; + + dp->drm = drm; + dp->sync_prop = drm_property_create_bool(drm, 0, "sync"); + dp->bpc_prop = drm_property_create_enum(drm, 0, "bpc", + xlnx_dp_bpc_enum, + ARRAY_SIZE(xlnx_dp_bpc_enum)); + dp->config.misc0 &= ~XDPTX_MAINSTRM_MISC0_MASK; + drm_object_attach_property(&connector->base, dp->sync_prop, false); + ret = xlnx_dp_set_bpc(dp, 8); + drm_object_attach_property(&connector->base, dp->bpc_prop, + ret ? ret : 8); + xlnx_dp_update_bpp(dp); + + drm_object_attach_property(&connector->base, + connector->dev->mode_config.gen_hdr_output_metadata_property, 0); + /* This enables interrupts, so should be called after DRM init */ + ret = xlnx_dp_init_aux(dp); + if (ret) { + dev_err(dp->dev, "failed to initialize DP aux"); + goto error_prop; + } + INIT_DELAYED_WORK(&dp->hpd_work, xlnx_dp_hpd_work_func); + INIT_DELAYED_WORK(&dp->hpd_pulse_work, xlnx_dp_hpd_pulse_work_func); + + return 0; + +error_prop: + drm_property_destroy(dp->drm, dp->bpc_prop); + drm_property_destroy(dp->drm, dp->sync_prop); + xlnx_dp_connector_destroy(&dp->connector); +error_encoder: + drm_encoder_cleanup(&dp->encoder); + + return ret; +} + +static void xlnx_dp_unbind(struct device *dev, + struct device *master, void *data) +{ + struct xlnx_dp *dp = dev_get_drvdata(dev); + + cancel_delayed_work_sync(&dp->hpd_work); + cancel_delayed_work_sync(&dp->hpd_pulse_work); + xlnx_dp_exit_aux(dp); + drm_property_destroy(dp->drm, dp->bpc_prop); + drm_property_destroy(dp->drm, dp->sync_prop); + xlnx_dp_connector_destroy(&dp->connector); + drm_encoder_cleanup(&dp->encoder); +} + +static void xlnx_dp_hpd_pulse_work_func(struct work_struct *work) +{ + struct xlnx_dp *dp; + int ret; + u8 link_status[DP_LINK_STATUS_SIZE]; + u8 bw_set, lane_set; + + dp = container_of(work, struct xlnx_dp, hpd_pulse_work.work); + + if (!dp->enabled) + return; + + if (!xlnx_dp_txconnected(dp)) { + dev_err(dp->dev, "incorrect HPD pulse received\n"); + return; + } + + /* Read Link information from downstream device */ + ret = drm_dp_dpcd_read_link_status(&dp->aux, link_status); + if (ret < 0) + return; + ret |= drm_dp_dpcd_read(&dp->aux, DP_LINK_BW_SET, &bw_set, 1); + ret |= drm_dp_dpcd_read(&dp->aux, DP_LANE_COUNT_SET, &lane_set, 1); + if (ret < 0) + return; + + bw_set &= DP_LINK_BW_SET_MASK; + if (bw_set != DP_LINK_BW_8_1 && + bw_set != DP_LINK_BW_5_4 && + bw_set != DP_LINK_BW_2_7 && + bw_set != DP_LINK_BW_1_62) + goto retrain_link; + + lane_set &= DP_LANE_COUNT_MASK; + if (lane_set != 1 && lane_set != 2 && lane_set != 4) + goto retrain_link; + + /* Verify the link status */ + ret = drm_dp_channel_eq_ok(link_status, lane_set); + if (!ret) + goto retrain_link; + + if (dp->config.hdcp2x_enable || dp->config.hdcp1x_enable) + schedule_delayed_work(&dp->hdcp_cp_irq_work, 0); + + return; + +retrain_link: + xlnx_dp_stop(dp); + xlnx_dp_start(dp); +} + +static void xlnx_dp_gen_drmif_pkt(struct xlnx_dp *dp, + struct hdmi_drm_infoframe drmif) +{ + struct xlnx_dp_infoframe *iframe = &dp->infoframe; + + memset(iframe, 0, sizeof(struct xlnx_dp_infoframe)); + + iframe->header.byte[0] = NON_AUDIOIF_PKT_ID; + iframe->header.byte[1] = NON_AUDIOIF_DRM_TYPE; + iframe->header.byte[2] = NON_AUDIOIF_LDATA_BYTECOUNT; + iframe->header.byte[3] = NON_AUDIOIF_SDP_VERSION; + iframe->payload.byte[0] = CTA_DRMIF_VERSION_NUMBER; + iframe->payload.byte[1] = CTA_DRMIF_LENGHT; + + iframe->payload.byte[2] = drmif.eotf & 0x7; + iframe->payload.byte[3] = drmif.metadata_type & 0x7; + + iframe->payload.byte[4] = drmif.display_primaries[0].x & 0xFF; + iframe->payload.byte[5] = drmif.display_primaries[0].x >> 8; + + iframe->payload.byte[6] = drmif.display_primaries[0].y & 0xFF; + iframe->payload.byte[7] = drmif.display_primaries[0].y >> 8; + + iframe->payload.byte[8] = drmif.display_primaries[1].x & 0xFF; + iframe->payload.byte[9] = drmif.display_primaries[1].x >> 8; + + iframe->payload.byte[10] = drmif.display_primaries[1].y & 0xFF; + iframe->payload.byte[11] = drmif.display_primaries[1].y >> 8; + + iframe->payload.byte[12] = drmif.display_primaries[2].x & 0xFF; + iframe->payload.byte[13] = drmif.display_primaries[2].x >> 8; + + iframe->payload.byte[14] = drmif.display_primaries[2].y & 0xFF; + iframe->payload.byte[15] = drmif.display_primaries[2].y >> 8; + + iframe->payload.byte[16] = drmif.white_point.x & 0xFF; + iframe->payload.byte[17] = drmif.white_point.x >> 8; + + iframe->payload.byte[18] = drmif.white_point.y & 0xFF; + iframe->payload.byte[19] = drmif.white_point.y >> 8; + + iframe->payload.byte[20] = drmif.max_display_mastering_luminance & 0xFF; + iframe->payload.byte[21] = drmif.max_display_mastering_luminance >> 8; + + iframe->payload.byte[22] = drmif.min_display_mastering_luminance & 0xFF; + iframe->payload.byte[23] = drmif.min_display_mastering_luminance >> 8; + + iframe->payload.byte[24] = drmif.max_cll & 0xFF; + iframe->payload.byte[25] = drmif.max_cll >> 8; + + iframe->payload.byte[26] = drmif.max_fall & 0xFF; + iframe->payload.byte[27] = drmif.max_fall >> 8; +} + +static void xlnx_dp_vsync_handler(struct xlnx_dp *dp) +{ + struct drm_connector_state *state = dp->connector.state; + struct hdmi_drm_infoframe frame; + struct xlnx_dp_infoframe *iframe = &dp->infoframe; + int i; + u32 fifosts = xlnx_dp_read(dp->dp_base, XDPTX_AUDIO_INFO_BUFF_STATUS); + + if (!(fifosts & (XDPTX_AUDIO_INFO_BUFF_FULL | + XDPTX_AUDIO_INFO_BUFF_OVERFLOW))) { + /* Write new audio info packet */ + for (i = 0; i < DP_INFOFRAME_FIFO_SIZE_WORDS; i++) { + xlnx_dp_write(dp->dp_base, + XDPTX_AUDIO_INFO_DATA_REG, + dp->tx_audio_data->buffer[i]); + } + + if (state->gen_hdr_output_metadata) { + drm_hdmi_infoframe_set_gen_hdr_metadata(&frame, state); + xlnx_dp_gen_drmif_pkt(dp, frame); + + xlnx_dp_write(dp->dp_base, XDPTX_AUDIO_INFO_DATA_REG, + iframe->header.data); + /* Write new hdr info packet */ + for (i = 0; i < (DP_INFOFRAME_FIFO_SIZE_WORDS - 1); i++) { + xlnx_dp_write(dp->dp_base, + XDPTX_AUDIO_INFO_DATA_REG, + iframe->payload.data[i]); + } + } + } +} + +static irqreturn_t xlnx_dp_irq_handler(int irq, void *data) +{ + struct xlnx_dp *dp = (struct xlnx_dp *)data; + u32 intrstatus; + u32 hpdduration; + + /* Determine what kind of interrupt occurred. */ + intrstatus = xlnx_dp_read(dp->dp_base, XDPTX_INTR_STATUS_REG); + + if (!intrstatus) + return IRQ_NONE; + if (intrstatus & XDPTX_INTR_HPDEVENT_MASK) { + dev_dbg_ratelimited(dp->dev, "hpdevent detected\n"); + } else if (intrstatus & XDPTX_INTR_HPDPULSE_MASK && + xlnx_dp_txconnected(dp)) { + /* + * Some monitors give HPD pulse repeatedly which cause + * HPD pulse function to be executed huge number of times. + * Hence HPD pulse interrupt is disabled if pulse duration + * is longer than 500 microseconds. + */ + hpdduration = xlnx_dp_read(dp->dp_base, XDPTX_HPD_DURATION_REG); + if (hpdduration >= 500) + xlnx_dp_write(dp->dp_base, XDPTX_INTR_MASK_REG, 0x10); + } + + if (intrstatus & XDPTX_INTR_CHBUFUNDFW_MASK) + dev_dbg_ratelimited(dp->dev, "underflow interrupt\n"); + if (intrstatus & XDPTX_INTR_CHBUFOVFW_MASK) + dev_dbg_ratelimited(dp->dev, "overflow interrupt\n"); + + if (intrstatus & XDPTX_INTR_HPDEVENT_MASK) + schedule_delayed_work(&dp->hpd_work, 0); + if (intrstatus & XDPTX_INTR_HPDPULSE_MASK) + schedule_delayed_work(&dp->hpd_pulse_work, 0); + if (intrstatus & XDPTX_INTR_EXTPKT_TXD_MASK) + xlnx_dp_vsc_pkt_handler(dp); + if (intrstatus & XDPTX_INTR_VBLANK_MASK) + xlnx_dp_vsync_handler(dp); + + return IRQ_HANDLED; +} + +static const struct component_ops xlnx_dp_component_ops = { + .bind = xlnx_dp_bind, + .unbind = xlnx_dp_unbind, +}; + +static ssize_t xlnx_hdcp_load_key(struct device *sysfs_dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret = 0; + struct xlnx_dp *dp = (struct xlnx_dp *)dev_get_drvdata(sysfs_dev); + struct xlnx_hdcptx *dptxhdcp = &dp->tx_hdcp; + + ret = xlnx_hdcp_tx_set_keys(dptxhdcp, (u8 *)buf); + if (ret) { + dev_dbg(dptxhdcp->dev, "failed to send HDCP key from Sysfs to wrapper\n"); + return ret; + } + return count; +} + +static DEVICE_ATTR(hdcp_key, XHDCP_KEY_WRITE_PERMISSION, NULL, xlnx_hdcp_load_key); + +static struct attribute *attrs[] = { + &dev_attr_hdcp_key.attr, + NULL, +}; + +static struct attribute_group attr_group = { + .attrs = attrs, +}; + +/** + * xlnx_dp_hdcp_dpcd_write - HDCP message write through dpcd interface + * @ref: callback reference pointer + * @offset: register offset + * @buf: write buffer + * @buf_size: number of bytes to write + * + * Return: buffer size on successful write, or the error code returned + * from the callee functions. + */ +static int xlnx_dp_hdcp_dpcd_write(void *ref, u32 offset, + void *buf, u32 buf_size) +{ + struct xlnx_dp *dp = (struct xlnx_dp *)ref; + u32 ret = 0; + + ret = drm_dp_dpcd_write(&dp->aux, offset, buf, buf_size); + if (ret < 0) { + dev_err(dp->dev, "dpcd write failed"); + return ret; + } + + return ret; +} + +/** + * xlnx_dp_hdcp_dpcd_read - HDCP message read through dpcd interface + * @ref: callback reference pointer + * @offset: register offset + * @buf: read buffer + * @buf_size: number of bytes to read + * + * Return: buffer size on successful read, or the error code returned + * from the callee functions. + */ +static int xlnx_dp_hdcp_dpcd_read(void *ref, u32 offset, + void *buf, u32 buf_size) +{ + struct xlnx_dp *dp = (struct xlnx_dp *)ref; + u32 ret = 0; + + ret = drm_dp_dpcd_read(&dp->aux, offset, buf, buf_size); + if (ret < 0) { + dev_err(dp->dev, "dpcd read failed"); + return ret; + } + + return ret; +} + +/** + * xlnx_dp_hdcp_status_update - HDCP status notification + * @ref: callback reference pointer + * @notification: HDCP notification + */ +static void xlnx_dp_hdcp_status_update(void *ref, u32 notification) +{ + struct xlnx_dp *dp = (struct xlnx_dp *)ref; + + switch (notification) { + case XHDCPTX_INCOMPATIBLE_RX: + dev_dbg(dp->dev, "HDCP TX compatible receiver is not found\n"); + break; + case XHDCPTX_AUTHENTICATION_BUSY: + dev_dbg(dp->dev, "HDCP TX Authentication Busy\n"); + break; + case XHDCPTX_AUTHENTICATED: + dev_dbg(dp->dev, "HDCP TX Authenticated\n"); + break; + case XHDCPTX_REAUTHENTICATE_REQUESTED: + dev_dbg(dp->dev, "HDCP TX Re-authentication Request received\n"); + break; + case XHDCPTX_DEVICE_IS_REVOKED: + dev_dbg(dp->dev, "HDCP TX , a device in the HDCP chain is revoked\n"); + break; + case XHDCPTX_NO_SRM_LOADED: + dev_dbg(dp->dev, "HDCP TX , no valid srm is loaded\n"); + break; + case XHDCPTX_UNAUTHENTICATED: + dev_dbg(dp->dev, "HDCP TX Unauthenticated\n"); + break; + default: + dev_dbg(dp->dev, "Error, HDCP is not initialized\n"); + break; + } +} + +/** + * xlnx_dp_hdcp_exit - HDCP module de-initialization + * @dp: displayPort IP core structure + * + * Return: 0 on success, or the status from called functions + */ +static int xlnx_dp_hdcp_exit(struct xlnx_dp *dp) +{ + struct xlnx_hdcptx *dptxhdcp = &dp->tx_hdcp; + int ret; + + if (!(dptxhdcp->hdcp1xenable || dptxhdcp->hdcp2xenable)) { + dev_info(dp->dev, "HDCP is not enabled in the system"); + return -EINVAL; + } + + ret = xlnx_dp_hdcp_reset(dp); + if (ret < 0) { + dev_err(dp->dev, "failed to reset HDCP"); + return ret; + } + + xlnx_hdcp_tx_timer_exit(dptxhdcp); + xlnx_hdcp_tx_exit(dptxhdcp); + + return 0; +} + +/** + * xlnx_timer_irq_handler - HDCP timer interrupt handler + * @irq: IRQ number of the interrupt being handled + * @data: Pointer to device structure + * + * Return: irq handler status + */ +static irqreturn_t xlnx_timer_irq_handler(int irq, void *data) +{ + struct xlnx_dp *dp = (struct xlnx_dp *)data; + struct xlnx_hdcptx *dptxhdcp = &dp->tx_hdcp; + + xlnx_hdcp_tmrcntr_interrupt_handler(dptxhdcp->xhdcptmr); + + return IRQ_HANDLED; +} + +/** + * xlnx_hdcp_init - HDCP module initialization + * @dp: displayPort IP core structure + * @pdev: platform structure + * + * Return: 0 on success, or return the error code from the called functions. + */ +static int xlnx_hdcp_init(struct xlnx_dp *dp, + struct platform_device *pdev) +{ + struct xlnx_hdcptx *dptxhdcp = &dp->tx_hdcp; + int ret; + + dptxhdcp->dev = dp->dev; + dptxhdcp->hdcp2xenable = dp->config.hdcp2x_enable; + dptxhdcp->hdcp1xenable = dp->config.hdcp1x_enable; + + if (dp->config.hdcp2x_enable) { + xlnx_dp_set(dp->dp_base, XDP_TX_HDCP2x_ENABLE, + XDP_TX_HDCP2x_ENABLE_BYPASS_DISABLE_MASK); + + dptxhdcp->xhdcp2x = xlnx_hdcp_tx_init(&pdev->dev, dp, dptxhdcp, + dp->dp_base + XDPTX_HDCP2X_OFFSET, + 0, XHDCPTX_HDCP_2X, dp->mode.lane_cnt, + XDPTX_HDCP, dp->hdcpx_keymgmt_base); + + if (IS_ERR(dptxhdcp->xhdcp2x)) { + dev_err(dp->dev, "failed to initialize HDCP2X module\n"); + return PTR_ERR(dptxhdcp->xhdcp2x); + } + } + dptxhdcp->xhdcptmr = + xlnx_hdcp_timer_init(&pdev->dev, dp->dp_base + XDPTX_HDCP_TIMER_OFFSET); + if (IS_ERR(dptxhdcp->xhdcptmr)) { + dev_err(dp->dev, "failed to initialize HDCP timer\n"); + return PTR_ERR(dptxhdcp->xhdcptmr); + } + dp->hdcptx_timer_irq = + platform_get_irq_byname(pdev, "dptxss_timer_irq"); + if (dp->hdcptx_timer_irq < 0) { + dev_err(dp->dev, "failed to get HDCP timer irq "); + return -EINVAL; + } + ret = devm_request_threaded_irq(dp->dev, dp->hdcptx_timer_irq, NULL, + xlnx_timer_irq_handler, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "dptxss_timer_irq", dp); + if (ret < 0) { + dev_err(dp->dev, "failed to register HDCP timer irq"); + return ret; + } + if (dp->config.hdcp1x_enable) { + dptxhdcp->xhdcp1x = xlnx_hdcp_tx_init(&pdev->dev, dp, dptxhdcp, + dp->dp_base + XDPTX_HDCP1X_OFFSET, + 0, XHDCPTX_HDCP_1X, dp->mode.lane_cnt, + XDPTX_HDCP, dp->hdcpx_keymgmt_base); + if (IS_ERR(dptxhdcp->xhdcp1x)) { + dev_err(dp->dev, "failed to initialize HDCP1X module\n"); + return PTR_ERR(dptxhdcp->xhdcp1x); + } + } + + ret = xlnx_hdcp_tx_set_callback(dptxhdcp, XDPTX_HDCP_DPCD_WRITE, + xlnx_dp_hdcp_dpcd_write); + if (ret < 0) { + dev_err(dp->dev, "failed to register HDCP DPCD Write Callback"); + return ret; + } + + ret = xlnx_hdcp_tx_set_callback(dptxhdcp, XDPTX_HDCP_DPCD_READ, + xlnx_dp_hdcp_dpcd_read); + if (ret < 0) { + dev_err(dp->dev, "failed to register HDCP DPCD Read Callback"); + return ret; + } + + ret = xlnx_hdcp_tx_set_callback(dptxhdcp, XDPTX_HDCP_STATUS, + xlnx_dp_hdcp_status_update); + if (ret < 0) { + dev_err(dp->dev, "failed to register HDCP Status Update Callback"); + return ret; + } + + INIT_DELAYED_WORK(&dp->hdcp_cp_irq_work, xlnx_dp_hdcp_cp_irq_func); + + return 0; +} + +static int xlnx_dp_parse_of(struct xlnx_dp *dp) +{ + struct xlnx_dp_config *config = &dp->config; + struct device_node *node = dp->dev->of_node; + u32 bpc; + int ret; + + if (dp->cfg->flags & XDPTX_VTC_OFFSET_CHANGE) { + ret = of_property_read_u32(node, "xlnx,vtc-offset", + &dp->vtc_off); + if (ret < 0) { + dev_err(dp->dev, "No vct offset in DT\n"); + return ret; + } + } else { + dp->vtc_off = XDPTX_VTC_BASE; + } + + config->hdcp1x_enable = of_property_read_bool(node, "xlnx,hdcp-enable"); + config->hdcp2x_enable = + of_property_read_bool(node, "xlnx,hdcp22-enable"); + + ret = of_property_read_u32(node, "xlnx,max-lanes", &config->max_lanes); + if (ret < 0) { + dev_err(dp->dev, "No lane count in DT\n"); + return ret; + } + if (config->max_lanes != 1 && config->max_lanes != 2 && + config->max_lanes != 4) { + dev_err(dp->dev, "Invalid max lanes in DT\n"); + return -EINVAL; + } + + ret = of_property_read_u32(node, "xlnx,max-link-rate", + &config->max_link_rate); + if (ret < 0) { + dev_err(dp->dev, "No link rate in DT\n"); + return ret; + } + if (config->max_link_rate != XDPTX_REDUCED_BIT_RATE && + config->max_link_rate != XDPTX_HIGH_BIT_RATE_1 && + config->max_link_rate != XDPTX_HIGH_BIT_RATE_2 && + config->max_link_rate != XDPTX_HIGH_BIT_RATE_3) { + dev_err(dp->dev, "Invalid link rate in DT\n"); + return -EINVAL; + } + + xlnx_dp_set_color(dp, DRM_FORMAT_RGB888); + + ret = of_property_read_u32(node, "xlnx,bpc", &bpc); + if (ret < 0) { + dev_err(dp->dev, "No color depth(bpc) in DT\n"); + return ret; + } + + switch (bpc) { + case 6: + config->misc0 |= XDPTX_MISC0_BPC6_MASK; + break; + case 8: + config->misc0 |= XDPTX_MISC0_BPC8_MASK; + break; + case 10: + config->misc0 |= XDPTX_MISC0_BPC10_MASK; + break; + case 12: + config->misc0 |= XDPTX_MISC0_BPC12_MASK; + break; + case 16: + config->misc0 |= XDPTX_MISC0_BPC16_MASK; + break; + default: + dev_err(dp->dev, "Not supported color depth in DT\n"); + return -EINVAL; + } + + config->audio_enabled = + of_property_read_bool(node, "xlnx,audio-enable"); + + config->versal_gt_present = + of_property_read_bool(node, "xlnx,versal-gt"); + + if (config->hdcp1x_enable) { + dp->hdcpx_keymgmt_base = syscon_regmap_lookup_by_phandle(node, + "xlnx,hdcp1x-keymgmt"); + if (IS_ERR(dp->hdcpx_keymgmt_base)) { + dev_err(dp->dev, "couldn't map hdcp1x Keymgmt registers\n"); + return -ENODEV; + } + } + + return 0; +} + +static int xlnx_dp_probe(struct platform_device *pdev) +{ + struct device_node *pnode = pdev->dev.of_node; + struct device_node *fnode; + struct platform_device *iface_pdev; + struct xlnx_dp *dp; + struct resource *res; + const struct of_device_id *match; + void *ptr; + unsigned int i; + int irq, ret; + + dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + + dp->tx_audio_data = + devm_kzalloc(&pdev->dev, sizeof(struct xlnx_dptx_audio_data), + GFP_KERNEL); + if (!dp->tx_audio_data) + return -ENOMEM; + + dp->dpms = DRM_MODE_DPMS_OFF; + dp->status = connector_status_disconnected; + dp->dev = &pdev->dev; + + match = of_match_node(xlnx_dp_of_match, pnode); + if (!match) + return -ENODEV; + + dp->cfg = match->data; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dp_base"); + dp->dp_base = devm_ioremap_resource(dp->dev, res); + if (IS_ERR(dp->dp_base)) { + dev_err(&pdev->dev, "couldn't map DisplayPort registers\n"); + return -ENODEV; + } + + ret = xlnx_dp_parse_of(dp); + if (ret < 0) + return ret; + + if (dp->config.versal_gt_present) { + dp->phy[0] = devm_phy_get(dp->dev, "dp-gtquad"); + if (IS_ERR(dp->phy[0])) + return dev_err_probe(dp->dev, ret, "failed to get phy\n"); + + ret = phy_init(dp->phy[0]); + if (ret) + goto error_phy; + + fnode = of_parse_phandle(pnode, "xlnx,xilinx-vfmc", 0); + if (!fnode) { + dev_err(&pdev->dev, "platform node not found\n"); + of_node_put(fnode); + } else { + iface_pdev = of_find_device_by_node(fnode); + if (!iface_pdev) { + of_node_put(pnode); + return -ENODEV; + } + + ptr = dev_get_drvdata(&iface_pdev->dev); + if (!ptr) { + dev_info(&pdev->dev, + "platform device not found -EPROBE_DEFER\n"); + of_node_put(fnode); + return -EPROBE_DEFER; + } + of_node_put(fnode); + } + } + + dp->axi_lite_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(dp->axi_lite_clk)) + return PTR_ERR(dp->axi_lite_clk); + + dp->tx_vid_clk = devm_clk_get(&pdev->dev, "tx_vid_clk"); + if (IS_ERR(dp->tx_vid_clk)) + dev_err(dp->dev, "failed to get vid clk stream1\n"); + + platform_set_drvdata(pdev, dp); + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 0); + xlnx_dp_write(dp->dp_base, XDPTX_MAINSTRM_ENABLE_REG, 0); + + dp->tx_link_config.vs_level = 0; + dp->tx_link_config.pe_level = 0; + + if (!dp->config.versal_gt_present) { + /* acquire vphy lanes */ + for (i = 0; i < dp->config.max_lanes; i++) { + char phy_name[16]; + + snprintf(phy_name, sizeof(phy_name), "dp-phy%d", i); + dp->phy[i] = devm_phy_get(dp->dev, phy_name); + if (IS_ERR(dp->phy[i])) { + ret = PTR_ERR(dp->phy[i]); + dp->phy[i] = NULL; + if (ret == -EPROBE_DEFER) { + dev_info(dp->dev, + "xvphy not ready -EPROBE_DEFER\n"); + return ret; + } + if (ret != -EPROBE_DEFER) + dev_err(dp->dev, "failed to get phy lane %s i %d, error %d\n", + phy_name, i, ret); + goto error_phy; + } + } + + ret = xlnx_dp_init_phy(dp); + if (ret) + goto error_phy; + } else { + ret = xlnx_dp_tx_gt_control_init(dp); + if (ret < 0) + return ret; + } + + ret = clk_prepare_enable(dp->axi_lite_clk); + if (ret) { + dev_err(dp->dev, "failed to enable axi_lite_clk (%d)\n", ret); + return ret; + } + + ret = clk_prepare_enable(dp->tx_vid_clk); + if (ret) { + dev_err(dp->dev, "failed to enable tx_vid_clk (%d)\n", ret); + goto tx_vid_clk_err; + } + + dp->aux.name = "Xlnx DP AUX"; + dp->aux.dev = dp->dev; + dp->aux.transfer = xlnx_dp_aux_transfer; + ret = drm_dp_aux_register(&dp->aux); + if (ret < 0) { + dev_err(dp->dev, "failed to initialize DP aux\n"); + goto error; + } + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + goto error; + } + ret = devm_request_threaded_irq(dp->dev, irq, NULL, + xlnx_dp_irq_handler, IRQF_ONESHOT, + dev_name(dp->dev), dp); + + if (ret < 0) + goto error; + + ret = sysfs_create_group(&dp->dev->kobj, &attr_group); + if (ret) + dev_err(dp->dev, "sysfs group creation failed to store keys"); + + if (dp->config.hdcp2x_enable || dp->config.hdcp1x_enable) { + ret = xlnx_hdcp_init(dp, pdev); + if (ret < 0) + goto error_hdcp; + } + if (dp->config.audio_enabled) { + if (dptx_register_aud_dev(dp->dev)) { + dp->audio_init = false; + dev_err(dp->dev, "dp tx audio init failed\n"); + goto error; + } else { + dp->audio_init = true; + dev_info(dp->dev, "dp tx audio initialized\n"); + } + } + + return component_add(&pdev->dev, &xlnx_dp_component_ops); + +error_hdcp: + xlnx_dp_hdcp_exit(dp); +tx_vid_clk_err: + clk_disable_unprepare(dp->axi_lite_clk); +error: + drm_dp_aux_unregister(&dp->aux); +error_phy: + if (!dp->config.versal_gt_present) { + dev_dbg(&pdev->dev, "xdprxss_probe() error_phy:\n"); + xlnx_dp_exit_phy(dp); + } else { + phy_exit(dp->phy[0]); + } + + return ret; +} + +static int xlnx_dp_remove(struct platform_device *pdev) +{ + struct xlnx_dp *dp = platform_get_drvdata(pdev); + + xlnx_dp_write(dp->dp_base, XDPTX_ENABLE_REG, 0); + if (dp->config.hdcp2x_enable || dp->config.hdcp1x_enable) + xlnx_dp_hdcp_exit(dp); + drm_dp_aux_unregister(&dp->aux); + if (!dp->config.versal_gt_present) + xlnx_dp_exit_phy(dp); + else + phy_exit(dp->phy[0]); + component_del(&pdev->dev, &xlnx_dp_component_ops); + sysfs_remove_group(&pdev->dev.kobj, &attr_group); + + return 0; +} + +MODULE_DEVICE_TABLE(of, xlnx_dp_of_match); + +static struct platform_driver dp_tx_driver = { + .probe = xlnx_dp_probe, + .remove = xlnx_dp_remove, + .driver = { + .name = "xlnx-dp-tx", + .of_match_table = xlnx_dp_of_match, + }, +}; + +module_platform_driver(dp_tx_driver); + +MODULE_AUTHOR("Rajesh Gugulothu "); +MODULE_DESCRIPTION("Xilinx FPGA DisplayPort Tx Driver"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_drv.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_drv.c @@ -0,0 +1,538 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx DRM KMS Driver + * + * Copyright (C) 2013 - 2018 Xilinx, Inc. + * + * Author: Hyun Woo Kwon + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xlnx_bridge.h" +#include "xlnx_crtc.h" +#include "xlnx_drv.h" +#include "xlnx_fb.h" +#include "xlnx_gem.h" + +#define DRIVER_NAME "xlnx" +#define DRIVER_DESC "Xilinx DRM KMS Driver" +#define DRIVER_DATE "20130509" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 + +#define MAX_CRTC 3 + +static uint xlnx_fbdev_vres = 2; +module_param_named(fbdev_vres, xlnx_fbdev_vres, uint, 0444); +MODULE_PARM_DESC(fbdev_vres, + "fbdev virtual resolution multiplier for fb (default: 2)"); + +/** + * struct xlnx_drm - Xilinx DRM private data + * @drm: DRM core + * @crtc: Xilinx DRM CRTC helper + * @fb: DRM fb helper + * @master: logical master device for pipeline + * @suspend_state: atomic state for suspend / resume + * @master_count: Counter to track number of fake master instances + */ +struct xlnx_drm { + struct drm_device *drm; + struct xlnx_crtc_helper *crtc; + struct drm_fb_helper *fb; + struct platform_device *master; + struct drm_atomic_state *suspend_state; + u32 master_count; +}; + +/** + * xlnx_get_crtc_helper - Return the crtc helper instance + * @drm: DRM device + * + * Return: the crtc helper instance + */ +struct xlnx_crtc_helper *xlnx_get_crtc_helper(struct drm_device *drm) +{ + struct xlnx_drm *xlnx_drm = drm->dev_private; + + return xlnx_drm->crtc; +} + +/** + * xlnx_get_align - Return the align requirement through CRTC helper + * @drm: DRM device + * + * Return: the alignment requirement + */ +unsigned int xlnx_get_align(struct drm_device *drm) +{ + struct xlnx_drm *xlnx_drm = drm->dev_private; + + return xlnx_crtc_helper_get_align(xlnx_drm->crtc); +} + +/** + * xlnx_get_format - Return the current format of CRTC + * @drm: DRM device + * + * Return: the current CRTC format + */ +uint32_t xlnx_get_format(struct drm_device *drm) +{ + struct xlnx_drm *xlnx_drm = drm->dev_private; + + return xlnx_crtc_helper_get_format(xlnx_drm->crtc); +} + +static void xlnx_output_poll_changed(struct drm_device *drm) +{ + struct xlnx_drm *xlnx_drm = drm->dev_private; + + if (xlnx_drm->fb) + drm_fb_helper_hotplug_event(xlnx_drm->fb); +} + +static const struct drm_mode_config_funcs xlnx_mode_config_funcs = { + .fb_create = xlnx_fb_create, + .output_poll_changed = xlnx_output_poll_changed, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static void xlnx_mode_config_init(struct drm_device *drm) +{ + struct xlnx_drm *xlnx_drm = drm->dev_private; + struct xlnx_crtc_helper *crtc = xlnx_drm->crtc; + + drm->mode_config.min_width = 0; + drm->mode_config.min_height = 0; + drm->mode_config.max_width = xlnx_crtc_helper_get_max_width(crtc); + drm->mode_config.max_height = xlnx_crtc_helper_get_max_height(crtc); + drm->mode_config.cursor_width = + xlnx_crtc_helper_get_cursor_width(crtc); + drm->mode_config.cursor_height = + xlnx_crtc_helper_get_cursor_height(crtc); +} + +static int xlnx_drm_open(struct drm_device *dev, struct drm_file *file) +{ + struct xlnx_drm *xlnx_drm = dev->dev_private; + + /* This is a hacky way to allow the root user to run as a master */ + if (!(drm_is_primary_client(file) && !dev->master) && + !file->is_master && capable(CAP_SYS_ADMIN)) { + file->is_master = 1; + xlnx_drm->master_count++; + } + + return 0; +} + +static int xlnx_drm_release(struct inode *inode, struct file *filp) +{ + struct drm_file *file = filp->private_data; + struct drm_minor *minor = file->minor; + struct drm_device *drm = minor->dev; + struct xlnx_drm *xlnx_drm = drm->dev_private; + + if (file->is_master && xlnx_drm->master_count) { + xlnx_drm->master_count--; + file->is_master = 0; + } + + return drm_release(inode, filp); +} + +static void xlnx_lastclose(struct drm_device *drm) +{ + struct xlnx_drm *xlnx_drm = drm->dev_private; + + if (xlnx_drm->fb) + drm_fb_helper_restore_fbdev_mode_unlocked(xlnx_drm->fb); +} + +static const struct file_operations xlnx_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = xlnx_drm_release, + .unlocked_ioctl = drm_ioctl, + .mmap = drm_gem_mmap, + .poll = drm_poll, + .read = drm_read, +#ifdef CONFIG_COMPAT + .compat_ioctl = drm_compat_ioctl, +#endif + .llseek = noop_llseek, +}; + +static struct drm_driver xlnx_drm_driver = { + .driver_features = DRIVER_MODESET | DRIVER_GEM | + DRIVER_ATOMIC, + .open = xlnx_drm_open, + .lastclose = xlnx_lastclose, + + DRM_GEM_DMA_DRIVER_OPS_VMAP_WITH_DUMB_CREATE(xlnx_gem_cma_dumb_create), + + .fops = &xlnx_fops, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, +}; + +static int xlnx_bind(struct device *dev) +{ + struct xlnx_drm *xlnx_drm; + struct drm_device *drm; + const struct drm_format_info *info; + struct platform_device *master = to_platform_device(dev); + struct platform_device *pdev = to_platform_device(dev->parent); + int ret; + u32 format; + + drm = drm_dev_alloc(&xlnx_drm_driver, &pdev->dev); + if (IS_ERR(drm)) + return PTR_ERR(drm); + + xlnx_drm = devm_kzalloc(drm->dev, sizeof(*xlnx_drm), GFP_KERNEL); + if (!xlnx_drm) { + ret = -ENOMEM; + goto err_drm; + } + + drm_mode_config_init(drm); + drm->mode_config.funcs = &xlnx_mode_config_funcs; + + ret = drm_vblank_init(drm, MAX_CRTC); + if (ret) { + dev_err(&pdev->dev, "failed to initialize vblank\n"); + goto err_xlnx_drm; + } + + drm->dev_private = xlnx_drm; + xlnx_drm->drm = drm; + xlnx_drm->master = master; + drm_kms_helper_poll_init(drm); + platform_set_drvdata(master, xlnx_drm); + + xlnx_drm->crtc = xlnx_crtc_helper_init(drm); + if (IS_ERR(xlnx_drm->crtc)) { + ret = PTR_ERR(xlnx_drm->crtc); + goto err_xlnx_drm; + } + + ret = component_bind_all(&master->dev, drm); + if (ret) + goto err_crtc; + + xlnx_mode_config_init(drm); + drm_mode_config_reset(drm); + dma_set_mask(drm->dev, xlnx_crtc_helper_get_dma_mask(xlnx_drm->crtc)); + + format = xlnx_crtc_helper_get_format(xlnx_drm->crtc); + info = drm_format_info(format); + if (info && info->depth && info->cpp[0]) { + unsigned int align; + + align = xlnx_crtc_helper_get_align(xlnx_drm->crtc); + xlnx_drm->fb = xlnx_fb_init(drm, info->cpp[0] * 8, 1, align, + xlnx_fbdev_vres); + if (IS_ERR(xlnx_drm->fb)) { + dev_err(&pdev->dev, + "failed to initialize drm fb\n"); + xlnx_drm->fb = NULL; + } + } else { + /* fbdev emulation is optional */ + dev_info(&pdev->dev, "fbdev is not initialized\n"); + } + + ret = drm_dev_register(drm, 0); + if (ret < 0) + goto err_fb; + + return 0; + +err_fb: + if (xlnx_drm->fb) + xlnx_fb_fini(xlnx_drm->fb); + component_unbind_all(drm->dev, drm); +err_crtc: + xlnx_crtc_helper_fini(drm, xlnx_drm->crtc); +err_xlnx_drm: + drm_mode_config_cleanup(drm); +err_drm: + drm_dev_put(drm); + return ret; +} + +static void xlnx_unbind(struct device *dev) +{ + struct xlnx_drm *xlnx_drm = dev_get_drvdata(dev); + struct drm_device *drm = xlnx_drm->drm; + + drm_dev_unregister(drm); + component_unbind_all(&xlnx_drm->master->dev, drm); + if (xlnx_drm->fb) { + xlnx_fb_fini(xlnx_drm->fb); + xlnx_drm->fb = NULL; + } + xlnx_crtc_helper_fini(drm, xlnx_drm->crtc); + drm_kms_helper_poll_fini(drm); + drm_mode_config_cleanup(drm); + drm_dev_put(drm); +} + +static const struct component_master_ops xlnx_master_ops = { + .bind = xlnx_bind, + .unbind = xlnx_unbind, +}; + +static int xlnx_of_component_probe(struct device *master_dev, + int (*compare_of)(struct device *, void *), + const struct component_master_ops *m_ops) +{ + struct device *dev = master_dev->parent; + struct device_node *ep, *port, *remote, *parent; + struct component_match *match = NULL; + int i; + + if (!dev->of_node) + return -EINVAL; + + component_match_add(master_dev, &match, compare_of, dev->of_node); + + for (i = 0; ; i++) { + port = of_parse_phandle(dev->of_node, "ports", i); + if (!port) + break; + + parent = port->parent; + if (!of_node_cmp(parent->name, "ports")) + parent = parent->parent; + parent = of_node_get(parent); + + if (!of_device_is_available(parent)) { + of_node_put(parent); + of_node_put(port); + continue; + } + + component_match_add(master_dev, &match, compare_of, parent); + of_node_put(parent); + of_node_put(port); + } + + parent = dev->of_node; + for (i = 0; ; i++) { + parent = of_node_get(parent); + if (!of_device_is_available(parent)) { + of_node_put(parent); + continue; + } + + if (!of_graph_is_present(parent)) { + of_node_put(parent); + break; + } + + for_each_endpoint_of_node(parent, ep) { + remote = of_graph_get_remote_port_parent(ep); + if (!remote || !of_device_is_available(remote) || + remote == dev->of_node) { + of_node_put(remote); + continue; + } else if (!of_device_is_available(remote->parent)) { + dev_warn(dev, "parent dev of %s unavailable\n", + remote->full_name); + of_node_put(remote); + continue; + } + component_match_add(master_dev, &match, compare_of, + remote); + of_node_put(remote); + } + of_node_put(parent); + + port = of_parse_phandle(dev->of_node, "ports", i); + if (!port) + break; + + parent = port->parent; + if (!of_node_cmp(parent->name, "ports")) + parent = parent->parent; + of_node_put(port); + } + + return component_master_add_with_match(master_dev, m_ops, match); +} + +static int xlnx_compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static int xlnx_platform_probe(struct platform_device *pdev) +{ + return xlnx_of_component_probe(&pdev->dev, xlnx_compare_of, + &xlnx_master_ops); +} + +static int xlnx_platform_remove(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &xlnx_master_ops); + return 0; +} + +static void xlnx_platform_shutdown(struct platform_device *pdev) +{ + component_master_del(&pdev->dev, &xlnx_master_ops); +} + +static int __maybe_unused xlnx_pm_suspend(struct device *dev) +{ + struct xlnx_drm *xlnx_drm = dev_get_drvdata(dev); + struct drm_device *drm = xlnx_drm->drm; + + drm_kms_helper_poll_disable(drm); + + xlnx_drm->suspend_state = drm_atomic_helper_suspend(drm); + if (IS_ERR(xlnx_drm->suspend_state)) { + drm_kms_helper_poll_enable(drm); + return PTR_ERR(xlnx_drm->suspend_state); + } + + return 0; +} + +static int __maybe_unused xlnx_pm_resume(struct device *dev) +{ + struct xlnx_drm *xlnx_drm = dev_get_drvdata(dev); + struct drm_device *drm = xlnx_drm->drm; + + drm_atomic_helper_resume(drm, xlnx_drm->suspend_state); + drm_kms_helper_poll_enable(drm); + + return 0; +} + +static const struct dev_pm_ops xlnx_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(xlnx_pm_suspend, xlnx_pm_resume) +}; + +static struct platform_driver xlnx_driver = { + .probe = xlnx_platform_probe, + .remove = xlnx_platform_remove, + .shutdown = xlnx_platform_shutdown, + .driver = { + .name = "xlnx-drm", + .pm = &xlnx_pm_ops, + }, +}; + +/* bitmap for master id */ +static u32 xlnx_master_ids = GENMASK(31, 0); + +/** + * xlnx_drm_pipeline_init - Initialize the drm pipeline for the device + * @pdev: The platform device to initialize the drm pipeline device + * + * This function initializes the drm pipeline device, struct drm_device, + * on @pdev by creating a logical master platform device. The logical platform + * device acts as a master device to bind slave devices and represents + * the entire pipeline. + * The logical master uses the port bindings of the calling device to + * figure out the pipeline topology. + * + * Return: the logical master platform device if the drm device is initialized + * on @pdev. Error code otherwise. + */ +struct platform_device *xlnx_drm_pipeline_init(struct platform_device *pdev) +{ + struct platform_device *master; + int id, ret; + + id = ffs(xlnx_master_ids); + if (!id) + return ERR_PTR(-ENOSPC); + + master = platform_device_alloc("xlnx-drm", id - 1); + if (!master) + return ERR_PTR(-ENOMEM); + + master->dev.parent = &pdev->dev; + ret = platform_device_add(master); + if (ret) + goto err_out; + + WARN_ON(master->id != id - 1); + xlnx_master_ids &= ~BIT(master->id); + return master; + +err_out: + platform_device_unregister(master); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(xlnx_drm_pipeline_init); + +/** + * xlnx_drm_pipeline_exit - Release the drm pipeline for the device + * @master: The master pipeline device to release + * + * Release the logical pipeline device returned by xlnx_drm_pipeline_init(). + */ +void xlnx_drm_pipeline_exit(struct platform_device *master) +{ + xlnx_master_ids |= BIT(master->id); + platform_device_unregister(master); +} +EXPORT_SYMBOL_GPL(xlnx_drm_pipeline_exit); + +static int __init xlnx_drm_drv_init(void) +{ + xlnx_bridge_helper_init(); + platform_driver_register(&xlnx_driver); + return 0; +} + +static void __exit xlnx_drm_drv_exit(void) +{ + platform_driver_unregister(&xlnx_driver); + xlnx_bridge_helper_fini(); +} + +module_init(xlnx_drm_drv_init); +module_exit(xlnx_drm_drv_exit); + +MODULE_AUTHOR("Xilinx, Inc."); +MODULE_DESCRIPTION("Xilinx DRM KMS Driver"); +MODULE_LICENSE("GPL"); --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_drv.h +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_drv.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx DRM KMS Header for Xilinx + * + * Copyright (C) 2013 - 2018 Xilinx, Inc. + * + * Author: Hyun Woo Kwon + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _XLNX_DRV_H_ +#define _XLNX_DRV_H_ + +struct drm_device; +struct xlnx_crtc_helper; + +struct platform_device *xlnx_drm_pipeline_init(struct platform_device *parent); +void xlnx_drm_pipeline_exit(struct platform_device *pipeline); + +uint32_t xlnx_get_format(struct drm_device *drm); +unsigned int xlnx_get_align(struct drm_device *drm); +struct xlnx_crtc_helper *xlnx_get_crtc_helper(struct drm_device *drm); +struct xlnx_bridge_helper *xlnx_get_bridge_helper(struct drm_device *drm); + +#endif /* _XLNX_DRV_H_ */ --- linux-xilinx-6.8.0.orig/drivers/gpu/drm/xlnx/xlnx_dsi.c +++ linux-xilinx-6.8.0/drivers/gpu/drm/xlnx/xlnx_dsi.c @@ -0,0 +1,1036 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx FPGA MIPI DSI Tx Controller driver. + * + * Copyright (C) 2017 - 2018 Xilinx, Inc. + * + * Author : Saurabh Sengar + * : Siva Rajesh J + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include